Problem
一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。
Solution
结论:若n%(m+1)==0,则后手赢,否则先手赢。
Proof
Code
if (n % (m + 1))
puts("first win");
else
puts("second win");
Practice
Brave Game(模板题)
kiki’s game(PN状态转巴什博弈)
Public Sale(变形)
悼念512汶川大地震遇难同胞——选拔志愿者
Problem
有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下:
(1)先手不能在第一次把所有的石子取完,至少取1颗;
(2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍。
约定取走最后一个石子的人为赢家,求必败态。
Solution
结论:先手必败,当且仅当石子数为斐波那契数。
Proof
先证明必要性,斐波那契数一定先手必败,可以用数学归纳法,大致思路就是一定能拆成两堆斐波那契数,不论先手怎样取,后手总能取到最后一颗
然后证明充分性,由“Zeckendorf定理”(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和,那么就回到了斐波那契数列里。
具体证明:斐波那契博弈(Fibonacci Nim)
Code
int f[N];
map<int,bool>mp;
int main()
{
f[1]=f[2]=1;
for(i=3;i<=N;++i)
{
f[i]=f[i-1]+f[i-2];
mp[f[i]]=1;
}
while(scanf("%d", &x) && x != 0)
puts(mp[x] == 1 ? "Second win" : "First win");
}
Practice