数论:博弈论
1.巴什博弈(BAshGame)
题目模板
- 只有一堆n个物品
- 两个人轮流取,每次只能取1~m个物品,谁先取完,谁胜利;(n,m是输入的随机数)
解题思路
1.当 n = m+1 时 第一个取的人不可能获胜;
2.•当 n = k(m + 1) + r 时 (k,r,s都是未知的整数)*
•先取者拿走 r 个,那么后者再拿(1~m)个
• 此时 n =(k-1)*(m+1)+s
•先取者再拿走s 个 最后总能造成 剩下n=k(m+1) 的局面*
3.•若n=k(m+1) 那么先取者必输*
求解巴什博弈函数
bool bash_g(int n,int m)
{
if(n%(m+1)!=0)
return true;
return false;
}
2.威佐夫博奕(Wythoff’s game)
题目模板
- 有两堆各若干个
- 两个人轮流从某堆或同时从两堆取同样多的物品
- 规定每次至少取一个,多者不限,最后取光的人胜利
解题思路
两堆石子的状态为 [a,b] (满足a<=b)
当 a=(k(√5+1)/2), b=a+k 时满足奇异局势,那么则先手输,反之则先手赢*
求解威佐夫博奕函数
bool Wythoff_Game(int a,int b)//b要大于a
{
double x=(1+sqrt(5))/2;
int k=b-a;
if(a==(int)(x*k))
return true;
return false;
}
3.尼姆博奕(Nimm’s Game)
题目模板
有多堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
解题思路
用0与每个数异或,如最后结果为0,则后手胜
设一数组a[n][m],令sum=0
循环与数组每一个数据异或(sum^=a[i][j])
sum最后等于0则后手胜
求解尼姆博弈函数
a[m]每堆物品的数量 sum=0
int Nimm_Game(int n,int m)//n堆物品,m个物品
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
sum = sum ^ a[i][j];
if(sum == 0)
return 0;
return 1;
}
4.斐波那契博弈
题目模板
- 有一堆个数为n的石子,游戏双方轮流取石子,
- 满足:
- 先手不能在第一次把所有的石子取完;
- 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)
求解斐波那契博弈函数 f[50]
int Fib_Game(int n)
{
f[1]=1;f[2]=1;
for(int i=3;i<=50;i++)
f[i] = f[i-1] + f[i-2];
if( 数组f 中包含 n )
return 1;//先手赢
return 0;
}
5.环形博弈
题目模板
n个石子围成一个环,每次取一个或者取相邻的2个(每个石子有序号)
求解
石子数<=2先手赢,否则后手赢,偶数先手,奇数后手
题目导航
1.巴什博弈
HDU 2147 kiki's game HDU 2149 Public Sale HDU 1846 Brave Game HDU 2188 悼念512汶川大地震遇难同胞——选拔志愿者
2.威佐夫博奕
HDU 1527 取石子游戏
3.尼姆博奕
洛谷
4.斐波那契博弈
HDU 2516 取石子游戏
5.环形博弈
hud3951
1745

被折叠的 条评论
为什么被折叠?



