三种基本博弈结论
1.巴什博奕:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行取石子;
4、 每走一步可以取走1到m个石子(至少1个,最多m个);
5、 最先取光石子的一方为胜。
当n=m+1时,无论怎么取,先手都是必败。
所以当n=p*(m+1)时,无论先手取几个,对手取的个数只要和自己取的个数加起来等于m+1,先手就会必败,此时为先手必败态。
当n=p*(m+1)+q时先手只要取走q个,对手就会陷入必败态,此时先手必胜。
例题:http://acm.hdu.edu.cn/showproblem.php?pid=1846
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+7; const ll mod=1e9+7; ll t,n,m; int main() { cin>>t; while(t--) { int f=0; cin>>n>>m; if(n%(m+1)==0)f=0; else f=1; if(f)cout<<"first"<<endl; else cout<<"second"<<endl; } }
2.威佐夫博奕:
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者
用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)( a[k] 其中 k 为下标 )表示两堆物品的数量并称其为局势。
如果面对(0,0),此时做选择的人已经输了,这种局势定义为奇异局势。
前几个奇异局势:
(0,0)
(1,2)
(3,5)
(4,7)
(6,10)
(8,13)
(9,15)
(11,18)
(12,20)
规律:(b[k]-a[k])为首项为0,公差为1的等差数列。
即a[0]=0,b[k]=a[k]+k;
a[k]是未在前面出现过的最小自然数.
当a<b时先手必败态可总结为a==(int)((b-a)*(1.0+sqrt(5))/2).
例题:http://poj.org/problem?id=1067
代码:
#include<iostream> #include<math.h> using namespace std; int a,b; int t; int main() { while(cin>>a>>b) { if(a>=b)swap(a,b); int temp=(b-a)*(1.0+sqrt(5.0))/2.0; if(a==temp)cout<<"0"<<endl; else cout<<"1"<<endl; } }
3.尼姆博弈
有任意堆各若干个物品,两个人轮流从任意一堆取任意多的物品,规定每次至少取1个,最后取光者得胜。
若有k堆物品,每堆含a[i]个(i=1,2...k)
设temp=a[1]^a[2]^a[3]^...^a[k];(^表示异或)
先手必败态:temp==0.