现在自己做 博弈论的题目也做了很长时间了,自己把自己做过的题目和感觉常出现的类型总结一下。
1.巴十博弈
这个是最基本的博弈类型。
公式很简单,n%(m+1)==0?LOST:WIN
变式:最少取p个,最多去q ,
if(n%(p+q)==0) printf("WIN\n");
else if(n%(p+q)<=p) printf("LOST\n");
else if(n%(p+q)>p) printf("WIN\n");
2.威佐夫博弈
每个T态是可以求出来的,用公式
if(a>b) a=a^b^(b=a);
double temp=double(b-a)/2.0*(sqrt(5)+1);
if(a==int(temp)) printf("0\n");
else printf("1\n");
3.Nimm
异或为0是必败态
变式:anti_Nimm
int n;
cin>>n;
int num=0;
int num1=0;
int num2=0;
while(n--)
{
int t;
cin>>t;
num^=t;
if(t==1)
num1++;
else
num2++;
}
if(num&&num2) //S2,S1态,必胜
cout<<"John"<<endl;
else if(!num2&&!num1%2) //T0态必胜
cout<<"John"<<endl;
else
cout<<"Brother"<<endl;
变式:阶梯博弈
//poj 1704阶梯博弈化为nimm
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<map>
const int MAX=0xfffffff;
using namespace std;
int a[1010];
int main( )
{
//freopen("1.txt","r",stdin);
int t;
while(cin>>t)
{
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n); //初始数据没有排序trick1
int sum=0;
a[-1]=0;
for(int i=n-1;i>=0;i-=2) //倒着取奇数,不知道为什么
sum^=a[i]-a[i-1]-1;
if(sum) cout<<"Georgia will win"<<endl;
else cout<<"Bob will win"<<endl;
}
}
return 0;
}