算法:巴什(Bash)博弈与斐波那契博弈

  在校招的时候经常遇到这个问题,今天被人提起,在这里总结一下。

http://blog.csdn.net/xuzengqiang/article/details/7763635

巴什博弈:只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个,最后取光者得胜。

显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。那么这个时候只要n%(m+1)!=0,先取者一定获胜。
斐波那契博弈:两个玩家,一堆石头,假设多于100块(总数未知),两人依次拿,最后拿光者赢,规则是:1. 第一个人不能一次拿光所有的;2. 第一次拿了之后, 每人每次最多只能拿对方前一次拿的数目的两倍。求先拿者必胜策略, 如果有的话。怎么证明必胜。
https://www.zhihu.com/question/20854624/answer/52756733
分析:这是斐波那契博弈,当且仅当石头个数是斐波那契数的时候先手必败。
让我们用第二数学归纳法证明:
为了方便,我们将 n 记为 f[i] 。
1、当 i=2 时,因为不能全部去完,先手只能取1颗,显然必败,结论成立。
2、假设当 i<=k 时,结论成立。
则当 i=k+1 时,f[i] = f[k]+f[k-1]。
则我们可以把这一堆石子看成两堆,简称 k 堆和 k-1 堆。
(一定可以看成两堆,因为假如先手第一次取的石子数大于或等于f[k-1],则后手可以直接取完f[k] ,因为 f[k] < 2*f[k-1] )
对于 k-1 堆,由假设可知,不论先手怎样取,后手总能取到最后一颗。下面我们分析一下后手最后取的石子数 x 的情况。
如果先手第一次取的石子数 y>=f[k-1]/3 ,则这小堆所剩的石子数小于 2y ,即后手可以直接取完,此时 x=f[k-1]-y ,则 x<=2/3*f[k-1] 。
我们来比较一下 2/3*f[k-1] 与 1/2*f[k] 的大小。即 4*f[k-1] 与 3*f[k] 的大小,对两值作差后不难得出,后者大。
所以我们得到,x<1/2*f[k] 。
即后手取完 k-1 堆后,先手不能一下取完 k 堆,所以游戏规则没有改变,则由假设可知,对于 k堆,后手仍能取到最后一 颗,所以后手必胜。
即 i=k+1 时,结论依然成立。
那么,当 n 不是Fibonacci数的时候,情况又是怎样的呢?
这里需要借助“Zeckendorf定理”(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和。
关于这个定理的证明,感兴趣的同学可以在网上搜索相关资料,这里不再详述。
分解的时候,要取尽量大的Fibonacci数。比如分解85:85在55和89之间,于是可以写成85=55+30,然后继续分解30,30 在21和34之间,所以可以写成30=21+9,依此类推,最后分解成85=55+21+8+1。
则我们可以把 n 写成  n = f[a1]+f[a2]+……+f[ap] 。(a1>a2>……>ap)
我们令先手先取完 f[ap] ,即最小的这一堆。由于各个f之间不连续,则 a(p-1) > ap  + 1 ,则有 f[a(p-1)] > 2*f[ap]。即后手 只能取 f[a(p-1)] 这一堆,且不能一次取完。
此时后手相当于面临这个子游戏(只有 f[a(p-1)]这一堆石子,且后手先取)的必败态,即先手一定可以取到这一堆的最后 一颗石子。

 

同理可知,对于以后的每一堆,先手都可以取到这一堆的最后一颗石子,从而获得游戏的胜利。

 

上面的分析其实有点问题,应该是只要我将斐波那契的点给对方拿到,对方必败。具体证明参考下面!

【以下回答并非标准证明过程,而是解题思考过程,谨供诸位参考】

想问题,从最简单处入手。

看到题目一阵迷茫,怎么办?
先凑着试试看呗。

如果只有2块石头,先行者必败:你拿1块,然后眼睁睁瞅着对手拿到了最后1块。
如果有3块石头,先行者……还是必败:不论拿1块还是2块,对手都能取完剩下的。
4块石头:诶,好像有一点不一样了,先拿1块,这样对手不管怎么取,先行者都能取到最后一块。
5块石头:先行还是不行……
6块石头:先行者拿1块,这样对手就处于5块石头先行但不能全拿完的情况之下了,必胜!
7块石头:先行者拿2块,依然令对手处于5块石头先行但不能全拿完的境地,必胜!看来,问题的关键,在于怎样让对手处于5块石头时先拿的境地了。
8块石头:先行者拿3块……咦,怎么对手一口气把剩下5块全拿完了?不行不行……那拿1块?对手拿2块。拿2块?对手拿1块。拿3块以上?更不行,对手直接拿完了。好像无论怎么拿,都会让对手陷自己于必败。看来8也是个必败之数。
9块石头:先行者拿1块,让对手陷入必败之8;
10块石头:先行者拿2块,让对手陷入必败之8;
11块石头:先行者拿3块,让对手陷入必败之8;
12块石头:先行者拿4块,让对手陷入必败之8……等等,这样对手不就可以全拿走了么?看来要分2步来,先拿1块,这样对手陷入必败之3,无论对手拿1块还是2块,先行者都拿对应的数字,就可以令对手陷入必败之8了;
13块石头:现在我们已经知道,胜负的关键,是让对手陷入必败之数。在那个数,先行者只要不能1次取完,就必然失败。所以,我们目标放在了最近的必败之数——8上。来,让我们算一下,13到8,咦,差5块石头。我们知道,5也是必败之数,看来无论怎么取,都无法避免对手抢到8,而后战胜我方了。原来,13也是个必败之数。
14块石头:先行者取1块,让对手陷入必败之13……
15块石头:……
16块石头:……

这么试下去,啥时候才是个尽头呀?
看来,必须得找一找规律。

我们先看看,目前为止,必败之数有哪些?
2,3,5,8,13

有没有觉得很眼熟?有没有想到些什么?
没错,这不就是传说中斐波那契数列的前几位么!
于是,大胆猜测:
当石头数为斐波那契数时,先行者必败;
否则,先行者必胜。



至于证明过程,就回到上文吧。

也就是我们在分析的时候,得到一个数字,先将其分解为数个斐波那契数,然后让对方拿到那些关键点,就能让对方必败!比如23,那我就先拿2,剩下21,由于21是斐波那契数,那么对方就必败。

声明:上面两个例子和解法的出处已经在博文中贴出了!

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值