📜  组合博弈论|组合3(脏数字木材和墨西哥混合货币)(1)

📅  最后修改于: 2023-12-03 14:56:50.739000             🧑  作者: Mango

组合博弈论 | 组合3(脏数字木材和墨西哥混合货币)

组合博弈论是博弈论的一个重要分支,研究的是多人博弈的胜负及策略问题。组合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(脏数字木材和墨西哥混合货币)的介绍。