Submission #41281946
Source Code Expand
import sys
def input():
return sys.stdin.readline().rstrip()
# Typical DP Contest M - 家
# R <=16なのでダブリング(10**9)*2**16で計算量は1966080になる
# どこから降りるか
# 最後は1から降りることになる
# (2**16)*30*16*16=503316480 間に合いそう
H, R = map(int, input().split())
G = [list(map(int, input().split())) for i in range(R)]
MOD = 10**9+7
#dp[i] 今いるフロアを含めて2**iフロア移動するとき、出発するフロアのjから到着するフロアのkに移動する場合の数
# フロアをまたがないsからtへの移動経路数 巡回セールスマン
dp_sum = [[0]*R for _ in range(R)]
for r in range(R):
dp_sum[r][r] = 1
for s in range(R):
# 初期化
dp = [[0]*R for _ in range(1<<R)]
dp[1<<s][s] = 1
# dp[S][i]の値を順に求めていく
# すでに訪問した都市の集合を表す整数がSで、最後に訪れた都市がiであるような状態に至る経路数
for S in range(1<<R):
for i in range(R):
#未訪問の場合スキップ
if S & (1 << i) == 0:continue
# 都市 jで場合分け jからiに来る
for j in range(R):
if j == i or S & (1 << j) == 0:continue
if G[j][i] == 0:continue
# 更新 Sで表される都市の集合都市vをのぞいてできる集合
dp[S][i] += dp[S & ~(1 << i)][j]
dp[S][i] %= MOD
for d in dp:
for t in range(R):
if s == t: continue
dp_sum[s][t] += d[t]
dp_sum[s][t] %= MOD
# print(dp_sum)
# dp[i][j][k]jから2**i回移動するとkにいる数
L = len(bin(H)[2:])#bit長
dp = [[[0]*R for i in range(R)] for _ in range(L)]
# 初期化
for i in range(R):
for j in range(R):
dp[0][i][j] = dp_sum[i][j]
for i in range(L-1):
for j in range(R):
for k in range(R):
for l in range(R):
# jからkに移動
dp[i+1][j][k] = (dp[i+1][j][k]+dp[i][j][l]*dp[i][l][k])%MOD
#2進数表記の逆順
S = bin(H)[2:][::-1]
prev = [0]*R
prev[0] = 1
for i in range(L):
if S[i] == "0":continue
cur = [0]*R
# jにいる場合の数とjからkに移動する数を掛け合わせる
for j in range(R):
for k in range(R):
cur[k] += prev[j]*dp[i][j][k]
cur[k] %= MOD
prev = cur
print(prev[0]%MOD)
Submission Info
| Submission Time | |
|---|---|
| Task | M - 家 |
| User | te1229 |
| Language | PyPy3 (7.3.0) |
| Score | 5 |
| Code Size | 2505 Byte |
| Status | AC |
| Exec Time | 2370 ms |
| Memory | 238172 KiB |
Judge Result
| Set Name | All | ||
|---|---|---|---|
| Score / Max Score | 5 / 5 | ||
| Status |
|
| Set Name | Test Cases |
|---|---|
| All | 00, 01, 02, 03, 04, 05, 06, 90, 91 |
| Case Name | Status | Exec Time | Memory |
|---|---|---|---|
| 00 | AC | 1708 ms | 237760 KiB |
| 01 | AC | 2085 ms | 237840 KiB |
| 02 | AC | 2318 ms | 238172 KiB |
| 03 | AC | 2370 ms | 238140 KiB |
| 04 | AC | 2344 ms | 237760 KiB |
| 05 | AC | 2305 ms | 236992 KiB |
| 06 | AC | 1015 ms | 170112 KiB |
| 90 | AC | 66 ms | 62192 KiB |
| 91 | AC | 60 ms | 66708 KiB |