この問題ではメモ化再帰を使う必要はないのですが、前述の問題を、練習のためメモ化再帰を使って解きなおします。
問題
C – 高橋くんのバグ探し
回答
defaultdict
defaultdict
をメモに使ってみます。
.format()
部分が読みにくいですが、メモの要素数を意識することなくメモを作成できるので、楽です。
import collections N, K = map(int, input().split()) T = [list(map(int, input().split())) for _ in range(N)] # メモ化再帰 memo = collections.defaultdict(bool) def dfs(num_q, value=0): if '{}_{}'.format(num_q, value) in memo.keys(): return memo['{}_{}'.format(num_q, value)] if num_q == N: if value == 0: return True return False for k in range(K): if dfs(num_q+1, value^T[num_q][k]): memo['{}_{}'.format(num_q, value)] = True return True memo['{}_{}'.format(num_q, value)] = False return False if dfs(0): print('Found') else: print('Nothing')
リスト
答えのメモ用と計算済みフラグ用で二つのリストを用意します。
N, K = map(int, input().split()) T = [list(map(int, input().split())) for _ in range(N)] # メモ化再帰 memo = [[False] * 128 for _ in range(N+1)] done = [[False] * 128 for _ in range(N+1)] def dfs(num_q, value=0): if done[num_q][value]: return memo[num_q][value] if num_q == N: if value == 0: return True return False for k in range(K): if dfs(num_q+1, value^T[num_q][k]): done[num_q][value] = True memo[num_q][value] = True return True done[num_q][value] = True memo[num_q][value] = False return False if dfs(0): print('Found') else: print('Nothing')
lru_cache
@functools.lru_cache
(user_function) を使いメモ化再帰を行います。
from functools import lru_cache N, K = map(int, input().split()) T = [list(map(int, input().split())) for _ in range(N)] @lru_cache(maxsize=2**20) def dfs(num_q, value=0): if num_q == N: if value == 0: return True return False for k in range(K): if dfs(num_q+1, value^T[num_q][k]): return True return False if dfs(0): print('Found') else: print('Nothing')