1.博弈论背景
- 博弈论的题目有如下特点:
有两名选手:
A.两名选手交替操作,每次一步,每步都在有限的合法集合中选取一种进行
B.在任何情况下,合法操作只取决于情况本身,与选手无关
C.游戏失败的条件为:当某位选手需要进行操作时,当前没有任何可以执行的合法操作。
2.巴什博奕
2.1 题目描述和思路
- 两个顶尖聪明的人在玩游戏,有n个石子,每人可以随便拿1−m个石子,不能拿的人为败者,问谁会胜利。
- 思路:巴什博奕是博弈论问题中基础的问题,它是最简单的一种情形对应一种状态的博弈。
2.2 从最简单的情景开始分析
- 当石子有1−m个时,毫无疑问,先手必胜
- 当石子有m+1个时,先手无论拿几个,后手都可以拿干净,先手必败
- 当石子有m+2−2m时,先手可以拿走几个,剩下m+1个,先手必胜
- 我们不难发现,面临m+1个石子的人一定失败。
- 这样的话两个人的最优策略一定是通过拿走石子,使得对方拿石子时还有m+1个
2.3 考虑往一般情况推广
- 设当前的石子数为n=k∗(m+1)+r:先手会首先拿走r个,接下来假设后手拿走x个,先手会拿走m+1−x个,这样博弈下去后手最终一定失败
- 设当前的石子数为n=k∗(m+1):假设先手拿x个,后手一定会拿m+1−x个,这样下去先手一定失败。
2.4 参考代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
if(n%(m+1)!=0) cout<<"first";
else cout<<"second";
cout<<endl;
}
return 0;
}
3.巴什博奕变形
3.1 题目描述和思考
- 作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的:
1、 总共n张牌;
2、 双方轮流抓牌;
3、 每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
4、 抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;
假设Kiki和Cici都是足够聪明并且每次都是Kiki先抓牌,请问谁能赢呢?
- 思路:有点类似于巴什博奕,总计一下这题的做法:
1.暴力手玩找规律
2.根据必胜态必败态的性质找规律
3.暴力计算SG函数找规律
4.最终都不难得到最后的规律:如果是三的倍数必胜,否则必败。原因很简单,三是一个必败点,因此无论是先手还是后手都会努力让石子的个数变为3的倍数
3.2 参考代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
while(cin>>t){
if(t%3!=0){
cout<<"Kiki";
}else{
cout<<"Cici";
}
cout<<endl;
}
return 0;
}