巴什博弈:
一堆n个物品,两人轮流取,最少1个,最多m个,最后取光者胜
结论: if(n%(m+1) == 0) 先手必败 else 先手必胜
推广:
只有一堆n个物品,两个人轮流从中取物,规定每次取数区间[s,m],当然如果少于s那么必须一次取完,最后取光者为胜。
结论:如果 0<n%(s+m)<=s 后手获胜
poj 2897
#include<bits/stdc++.h>
using namespace std;
int n,m,s;
int main()
{
while(~scanf("%d%d%d",&n,&s,&m))
{
if(n % (m + s) > 0 && n % (m + s) <= s)
printf("LOST\n");
else printf("WIN\n");
}
return 0;
}
Nim博弈:
三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
结论: 当石子堆数为n堆时,则推广为当对每堆的数目进行异或之后值为零是必败态
威佐夫博弈:
两堆物品,两人轮流取,要求(1)从其中一堆取至少一件物品,至多不限(2)从两堆中同时取相同件物品
最后取光者胜
结论:两堆(x,y),(x > y) 令z = y - x
如果w = x ,先手必败 else 先手必胜
poj 1527
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
while(~scanf("%d%d",&n,&m))
{
int t = abs(n - m);
if(min(n,m) == int(((sqrt(5) + 1) / 2) * t)) printf("0\n");
else printf("1\n");
}
return 0;
}
斐波那契博弈:
1堆石子有n个(n>1),两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍,先取完者胜
结论:判断石子数是否为斐波那契数,若n = f(k),则先手必败。
在斐波那契数列中,f(i) = f(i - 1) + f (i - 2),所以很好证明f(i) <= f(i-1)* 2.
Poj 2516
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[100000],n;
void init()
{
f[1] = f[2] = 1;
for(int i = 3;i <= 50; ++i)
f[i] = f[i - 1] + f[i - 2];
}
int main()
{
init();
while(~scanf("%lld",&n))
{
if(!n) break;
bool flag = 0;
for(int i = 1;i <= 50; ++i)
if(n == f[i])
{
flag = 1;
break;
}
if(!flag) printf("First win\n");
else printf("Second win\n");
}
return 0;
}