博弈一直没怎么学,每次遇到了就看看题解,这两周被atc和牛客军训了,还都没做出来,思考了一下,暂且记录我粗浅的认知。
如果我未来能好好学学,可能回来更新。
@lru_cache(None)
def dfs(m, n):
if xxd递归出口:
return False/True
for i in range(1, (m + 1) // 2): # 枚举所有选择
if not dfs(i, n): # 注意这个not,后继态必败,当前必胜
return True
return False
例题: 小d的博弈
# Problem: 小d的博弈
# Contest: NowCoder
# URL: https://ac.nowcoder.com/acm/contest/53366/E
# Memory Limit: 524288 MB
# Time Limit: 2000 ms
import sys
from functools import lru_cache
RI = lambda: map(int, sys.stdin.buffer.readline().split())
RS = lambda: map(bytes.decode, sys.stdin.buffer.readline().strip().split())
RILST = lambda: list(RI())
DEBUG = lambda *x: sys.stderr.write(f'{str(x)}\n')
MOD = 10 ** 9 + 7
PROBLEM = """
"""
@lru_cache(None)
def dfs(m, n):
if m <= 2 and n <= 2:
return False
if m <= 2 or n <= 2:
return True
for i in range(1, (m + 1) // 2):
if not dfs(i, n):
return True
for j in range(1, (n + 1) // 2):
if not dfs(m, j):
return True
return False
# 603 ms
def solve1():
n, m = RI()
y = x = 0
while n > 2:
n = (n - 1) // 2
x += 1
while m > 2:
m = (m - 1) // 2
y += 1
if x != y:
print('Alice')
else:
print('Bob')
# 573 ms
def solve():
n, m = RI()
if (n + 1).bit_length() != (m + 1).bit_length():
print('Alice')
else:
print('Bob')
if __name__ == '__main__':
t, = RI()
for _ in range(t):
solve()
# for i in range(1, 40):
# for j in range(1, 40):
# print('X' if dfs(i, j) else 'O', end=' ')
# print()
链接: 464. 我能赢吗
class Solution:
def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
@cache
def dfs(used_numbers,total):
for i in range(maxChoosableInteger):
if (used_numbers>>i)&1 == 0: # used_numbers第i位是0,即i未被使用,他可以用
if total + i +1 >= desiredTotal:
return True
if dfs(used_numbers|(1<<i),total+i+1) == False: # 下一步的操作者,即下一个人输掉
return True
return False
return (1+maxChoosableInteger)*maxChoosableInteger//2 >= desiredTotal and dfs(0,0)
链接: 292. Nim 游戏
class Solution:
def canWinNim(self, n: int) -> bool:
return bool(n%4)