📅  最后修改于: 2023-12-03 14:56:50.739000             🧑  作者: Mango
组合博弈论是博弈论的一个重要分支,研究的是多人博弈的胜负及策略问题。组合3是一个著名的博弈问题,它包含两个子问题:脏数字木材和墨西哥混合货币。
脏数字木材是一个基于桶排序的博弈。给定一个长度为n的数组a,每次操作可以选择一段区间[l, r],将区间内所有数字变为它们的最小值。当所有数字都相等时,游戏结束。
该博弈的解法是nim游戏,因为每次操作相当于将一些木棍切成相等长度。可以通过先将每个数看成一个二进制数,然后计算出每一位的1的个数,将每一位的1的个数取模2,得到一个长度为30的01串,将其看作一个nim数,再将30个nim数看成一个sg数,最后将30个sg数的异或和作为整个博弈的sg数。
代码示例:
def sg(x):
res = 0
for i in range(30):
cnt = 0
for j in range(len(x)):
if x[j] & (1 << i):
cnt += 1
res ^= cnt % 2 * (1 << i)
return res
墨西哥混合货币是一个基于nim游戏的博弈。给定一个长度为n的正整数数组a,每次操作可以将一个数减去它的因数。如果有一个人不能操作,则游戏结束,另一个人胜利。
该博弈的解法是dfs+记忆化搜索,可以使用类似sg函数来计算出每个状态的sg值,再使用记忆化搜索求解。
代码示例:
def dfs(nums):
if tuple(nums) in mem:
return mem[tuple(nums)]
res = 0
for i in range(len(nums)):
divisor = [j for j in range(1, nums[i]+1) if nums[i]%j==0]
for j in range(len(divisor)):
temp = nums.copy()
temp[i] -= divisor[j]
if all(x==0 for x in temp):
res = 1
break
res |= not dfs(temp)
if res == 1:
break
mem[tuple(nums)] = res
return res
以上是组合博弈论 | 组合3(脏数字木材和墨西哥混合货币)的介绍。