巴什博奕,威佐夫博奕,尼姆博奕,斐波那契博弈模板
2017-08-21 17:46
351 查看
1.巴什博奕
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。
显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。
2.威佐夫博奕
这种博弈比前面一种要稍微复杂一点。我们来看下下面这个游戏。
有两堆火柴棍,每次可以从某一堆取至少1根火柴棍(无上限),或者从两堆取相同的火柴棍数。最后取完的是胜利者。
只要记住公式:a[i] = [i*(1+√5)/2](这里的中括号表示向下取整) b[i] = a[i]+i;
我们用a[i]表示失败态中的第一个,b[i]表示失败态中的第二个.(i从0开始).
3.尼姆博奕
指的是这样的一个博弈游戏,目前有任意堆石子,每堆石子个数也是任意的,双方轮流从中取出石子,规则如下:
1)每一步应取走至少一枚石子;每一步只能从某一堆中取走部分或全部石子;
2)如果谁取到最后一枚石子就胜。
判断当前局势是否为必胜(必败)局势:
把所有堆的石子数目用二进制数表示出来,当全部这些数按位异或结果为0时当前局面为必败局面,否则为必胜局面;
4.斐波那契博弈
有一堆个数为n的石子,游戏双方轮流取石子,满足:
1)先手不能在第一次把所有的石子取完;
2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。
约定取走最后一个石子的人为赢家,求必败态。
这个游戏叫做斐波那契博弈,肯定和斐波那契数列:f
:1,2,3,5,8,13,21,34,55,89,… 有密切的关系。如果试验一番之后,可以猜测:先手胜当且仅当n不是斐波那契数。换句话说,必败态构成斐波那契数列。
至于本题的模板,我们来看一道模板题:点击打开链接
这里没有给出具体的证明,只是简单的模板,如果学习更多再补充
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。
显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int main() { int N, num, limit; scanf("%d", &N); while(N--) { scanf("%d%d", &num, &limit); if(num % (limit + 1) != 0) //必胜局面 printf("Win\n"); else printf("Lose\n"); } return 0; }
2.威佐夫博奕
这种博弈比前面一种要稍微复杂一点。我们来看下下面这个游戏。
有两堆火柴棍,每次可以从某一堆取至少1根火柴棍(无上限),或者从两堆取相同的火柴棍数。最后取完的是胜利者。
只要记住公式:a[i] = [i*(1+√5)/2](这里的中括号表示向下取整) b[i] = a[i]+i;
我们用a[i]表示失败态中的第一个,b[i]表示失败态中的第二个.(i从0开始).
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int main() { int num1, num2, tmp; //第一堆剩的数量为num1,第二堆剩num2 while(scanf("%d%d", &num1, &num2) != EOF) { if(num1 > num2) swap(num1, num2); tmp = floor((num2 - num1) * (1 + sqrt(5.0)) / 2.0); //黄金分割 if(tmp == num1) printf("Lose\n"); //奇异局势必败 else printf("Win\n"); } return 0; }
3.尼姆博奕
指的是这样的一个博弈游戏,目前有任意堆石子,每堆石子个数也是任意的,双方轮流从中取出石子,规则如下:
1)每一步应取走至少一枚石子;每一步只能从某一堆中取走部分或全部石子;
2)如果谁取到最后一枚石子就胜。
判断当前局势是否为必胜(必败)局势:
把所有堆的石子数目用二进制数表示出来,当全部这些数按位异或结果为0时当前局面为必败局面,否则为必胜局面;
#include<iostream> using namespace std; int temp[ 20 ]; //火柴的堆数 int main() { int i, n, min; while( cin >> n ) { for( i = 0; i < n; i++ ) cin >> temp[ i ]; //第i个火柴堆的数量 min = temp[ 0 ]; for( i = 1; i < n ; i++ ) min = min^temp[ i ]; //按位异或 if( min == 0 ) cout << "Lose" << endl; //输 else cout << "Win" << endl; //赢 } return 0; }
4.斐波那契博弈
有一堆个数为n的石子,游戏双方轮流取石子,满足:
1)先手不能在第一次把所有的石子取完;
2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。
约定取走最后一个石子的人为赢家,求必败态。
这个游戏叫做斐波那契博弈,肯定和斐波那契数列:f
:1,2,3,5,8,13,21,34,55,89,… 有密切的关系。如果试验一番之后,可以猜测:先手胜当且仅当n不是斐波那契数。换句话说,必败态构成斐波那契数列。
至于本题的模板,我们来看一道模板题:点击打开链接
这里没有给出具体的证明,只是简单的模板,如果学习更多再补充
相关文章推荐
- 博弈:巴什博奕(Bash Game)威佐夫博奕(Wythoff Game)尼姆博奕(Nimm Game)
- 博弈论模板(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈的三个巨人 巴什博奕 威佐夫博奕 尼姆博奕
- 三大数学博弈:巴什博奕 威佐夫博奕 尼姆博奕
- 博弈论-巴什博弈、威佐夫博奕、尼姆博奕
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- ACM博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈,sg函数)
- 三种典型的博弈论问题(巴什博奕、威佐夫博奕、尼姆博奕)
- 博弈入门(巴什博弈、斐波那契博弈、威佐夫博奕)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 关于博弈基础知识的总结:巴什博弈(Bash Game)、威佐夫博奕(Wythoff Game)、尼姆博奕(Nim Game)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈,三种博弈 巴什博奕,尼姆博奕,威佐夫博弈
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈) (转载)
- 取石子 斐波那契博弈 华为oj
- poj 1067 取石子游戏(威佐夫博弈模板)
- hdu 2516 斐波那契博弈