取石子游戏(2516)

来源:互联网 发布:调度数据专网 编辑:程序博客网 时间:2024/04/28 17:18
Problem Description
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".
 

Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
 

Output
先取者负输出"Second win". 先取者胜输出"First win". 
参看Sample Output.
 

Sample Input
213100000
 

Sample Output
Second winSecond winFirst win

这个游戏的一种版本是这个样子的:

桌子上有若干个石子,两人轮流取。第一个人可以取走任意多个,但至少取走一个,至少留有一个。此后的过程中,必须取走一个,但不得超过对手上次取走的两倍。拿到最后一个石子的赢得游戏。

好了,看起来似乎很简单,因为它和这个很像:

桌子上有若干个石子,两人轮流取。每次必须取走一个,但不得超过三个。拿到最后一个石子的赢得游戏。

相信第二个游戏大家都觉得很简单就可以找到最优策略。可惜的是,我说的这个版本要比第二个难了不少。因为它居然和斐波那契数列有关系,关系如下:

当且仅当石子数量不是斐波那契数,先手有必胜策略。

想不通吧,一眼看上去,这道题目和斐波那契数列一点联系都找不到。但是接下来我将证明这个结论是正确的,并给出一种最优策略。首先让我们来看看这些东西:
0. 记斐波那契数列的第i项为Fi
1. Fi+1 = Fi + Fi-1 --这是斐波那契数列的定义
2. Fi ≤ 2×Fi-1 --把左边按(1)式拆开就很容易证明
3. Fi > 4/3×Fi-1 --4/3×Fi-1 = Fi-1+Fi-1/3 < Fi-1+Fi-2 = Fi

下面我们用[a,b]来表示游戏当前的局面,其中a表示桌上剩余的石子数量,b表示轮到行动的玩家可以拿走的石子数量。也就是说,如果b≥a就赢了。
4. 如果轮到先手行动时局面为[a,b]时,无论先手如何行动后手都有有必胜策略。那么对于任意的b’ < b,当轮到先手行动时的局面为[a,b']时,后手仍然有必胜策略。 --这个是个简单的逻辑推理。

好了,我们开始证明当n=Fi时,后手有必胜策略。

显然,当游戏开始的时候,局面为[Fi,Fi-1]。先手的可以拿走任意多个,但是它一定不愿意拿走大于等于Fi/3个石子,因为这以为着后手可以在后一轮拿走剩下的所有石子。设先手拿走k < Fi/3个石子。则局面变为[Fi-k,2k]。

我们可以把其中的Fi拆开,表示为[Fi-1+Fi-2-k,2k],然后呢,如果满足Fi-2≤3k,那么后手只需要取走Fi-2-k个石子就能让局面回到类似于[Fi-1,b]的样子,因为此时b = 2×(Fi-2-k) ≤ 4/3×Fi-2 < Fi-1,意味着先手不能在下一轮拿走完剩下的石子,重新进入我们的圈套。

可是如果不满足满足Fi-2<3k呢?嘿嘿,奸诈的夜弓继续把Fi-2拆分成更小的F,夜弓重复这个步骤,每次都拆分最小的那个F[注1],直到某一步拆分得到了相邻的两个斐波那契数Fj和Fj+1使得Fj≤3k。那么我们取走Fj-k个石子[注2],由于我们前面所说的2×(Fj-k) ≤ 4/3×Fj < Fj+1仍然成立,所以对手在下一回合中还是不能将Fj+1全部取走,所以很我们很愉快的继续玩我们的把戏。如果先手足够聪明,他能够拖延时间,但最后摆在他面前的必然是一个[3,2]的布局,显然无论他如何行动都将输掉游戏。

那么,如果开始的时候石子数目不是斐波那契数呢?难道后手不能用类似的方法赢得游戏吗?是的,因为先手可以在第一步拿走任意数目的石子,比如拿走适当数目的石子使得剩下的为一个斐波那契数或者若干个斐波那契数之和。而这一点非常容易做到。有兴趣的读者可以自己思考这个问题。^_^

注1:每次都拆分最小的那个F可以保证我们把石子数目拆分成了不同的斐波那契数,这点非常重要。

注2:Fj-k > 0,因为3Fj > Fj+Fj+1 = Fj+2 > 3k,否则分解在Fj+2处就停止。