算法之博弈论

本文介绍了博弈论的基本概念,并深入探讨了巴什博奕问题,包括题目描述、思路分析以及如何从简单情景推广到一般情况。同时,文章还讨论了巴什博奕的变形,提出了在抓牌游戏中寻找获胜策略的方法,即牌数为三的倍数时先手必胜。
摘要由CSDN通过智能技术生成

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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值