基础组合游戏合集
作者:互联网
简介
本文介绍了博弈论中的四种基础组合游戏,并给出了证明,如有错误之处欢迎指正
尼姆博弈(Nim)
定义
尼姆博弈的定义是:
给定 \(n\) 堆物品,第 \(i\) 堆物品有 \(A_i\) 个,两人轮流取,每次可以任选一堆取走任意多个物品,可以取光但不能不取,最后把物品全部取完者胜利
判断先手是否有必胜策略
结论
\(A_1\oplus A_2\oplus\cdots\oplus A_n\not=0\) 时先手必胜
证明
参考 尼姆博弈原理与证明
例题
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int m;
while(cin >> m) {
int x, res = 0;
for(int i = 1; i <= m; i++) {
scanf("%d", &x);
res = res ^ x;
}
printf("%s\n", res ? "Yes" : "No");
}
return 0;
}
巴什博弈(Bash)
定义
巴什博弈的定义是:
有一堆物品,两人轮流取,每次可以取 \(1\) 到 \(m\) 个物品,最后把物品全部取完者胜利
现在给出初始的物品数 \(n\) 和 \(m\) ,判断先手是否有必胜策略
结论
\(m+1\mid n\) 时先手必败
证明
参考 巴什博弈原理与证明
例题
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while(t--) {
ll n, m;
scanf("%lld%lld", &n, &m);
printf("%s\n", n % (m + 1) ? "first" : "second");
}
return 0;
}
斐波那契博弈(Fibonacci)
定义
斐波那契博弈的定义是:
有一堆物品,两人轮流取,先手第一次可以取任意个但不能全部取完。之后每次取的数量必须大于等于 \(1\) 且小于等于上次取的数量的两倍,最后把物品全部取完者胜利
现在给出初始的物品数 \(n\) ,判断先手是否有必胜策略
结论
\(n\) 为斐波那契数数时先手必败
证明
参考 斐波那契博弈原理与证明
例题
#include<bits/stdc++.h>
using namespace std;
int f[200 + 5];
map<int, bool> mp;
int main()
{
f[1] = f[2] = 1;
for(int i = 3; i <= 50; i++) {
f[i] = f[i - 1] + f[i - 2];
mp[f[i]] = true;
}
int x;
while(scanf("%d", &x) != EOF && x)
printf("%s\n", mp[x] ? "Second win" : "First win");
return 0;
}
威佐夫博弈(Wythoff)
定义
威佐夫博弈的定义是:
有两堆若干个物品,两人轮流从某一堆物品中取至少一个或同时从两堆中取相同数量的物品,不能不取,最后把物品全部取完者胜利
现在给出两堆物品的数量 \(n,m\) 判断先手是否有策略必胜
结论
如果 \(n\leq m\) 那么 \(n=\lfloor(m-n)(\frac{\sqrt 5 + 1}{2})\rfloor\) 时先手必败
证明
参考 威佐夫博弈原理与证明
例题
#include<bits/stdc++.h>
using namespace std;
const double r = (sqrt(5.0) + 1.0) / 2.0;
int main()
{
int a, b;
cin >> a >> b;
if(a < b)
swap(a, b);
cout << !(b == (int)((a - b) * r)) << endl;
return 0;
}
标签:博弈,游戏,组合,int,证明,物品,include,合集,定义 来源: https://www.cnblogs.com/tttkf/p/15897740.html