威佐夫博奕
威佐夫博奕
题目
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
输入示例
输入: 1 2
输出: false
解释: 无论你怎么取,都是对方赢
输入: 2 2
输出: true
解释: 直接从两堆中取2
解题思路
这种情况下是颇为复杂的。我们用(ak,bk)
(ak ≤ bk ,k=0,1,2,…,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。
前几个奇异局势是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)…
我们观察一下这些状态,可以找到两条规律。
- 我们假设从小到大排的第k个必败状态是(x, y),并且x < y。我们可以发现y = x + k。也就是说必败状态两个数的差值是递增的。
- 每一个必败状态的差值都各不相同。
反证法:
假设(a, a+k)
, (b, b+k)
都是必败状态,并且a < b
。那么先手在面临(b, b+k)的时候,只需要在两堆当中同时取走b-a
个石子,那么给后手的局面就是(a, a+k)
。对于后手来说,这是一个必败的局面,这就和(b, b+k)
先手必败矛盾,所以不存在两个必败局面的差值相等。
求证
为了写出通项公式,我们需要引入Betty定理。
设a和b是两个正无理数,并且
那么对于两个集合A
,B
:
有下面两个结论:
证明过程:
(1) Betty定理及证明_Michael_GLF的博客-CSDN博客_贝蒂瑞利定理
我们不妨假设存在这样的a, b同时满足Betty定理与必败状态的性质:
带入可以得到:
解得:,算出的结果居然是黄金分割比。
由此可以得出奇异局势的条件:主要看公式(4)
代码
public boolean helper(int a,int b){
if(a > b){
int t=a;
a=b;
b=t;
}
int n=b-a;
if((int)(n*(1+Math.sqrt(5))/2)==a) return false;
else return true;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义