笔记---简单博弈论

公平组合游戏(ICG)
满足一下几个特征:
1.两名玩家交替行动。
2.在游戏进程的任意时刻,可以执行的合法行动与轮到哪名玩家无关。
3.不能行动的玩家判为失败
如果满足以上特征,那么就是一个公平组合游戏
另一种游戏叫做有向图游戏:
给定一个有向无环图,图中有一个唯一的起点,在起点上放有一枚棋子,两名玩家交替的把这枚棋子沿有向边进行移动,每次可以一定一步,最终无法移动的人判为失败

其中Nim游戏属于公平组合游戏

AcWing.891.Nim游戏
给定 n n n 堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式
第一行包含整数 n n n
第二行包含 n n n 个数字,其中第 i i i 个数字表示第 i i i 堆石子的数量。

输出格式
如果先手方必胜,则输出 Yes。否则,输出 No

数据范围
1 ≤ n ≤ 1 0 5 , 1 ≤ 每堆石子数 ≤ 1 0 9 1≤n≤10^{5},1≤每堆石子数≤10^{9} 1n105,1每堆石子数109

输入样例:

2
2 3

输出样例:

Yes

先手必败状态是指:遇到了无法操作的情况,必然会输掉游戏。
先手必胜状态是指:当我们进行完了这一步操作之后,对手一定会陷入必败状态

结论:
如果n堆的数量为: a 1 , a 2 , . . . . . . , a n a_{1},a_{2},......,a_{n} a1,a2,......,an,那么:
使得 a a a1 ^ a a a2 ^… a a an
如果结果为0,那么先手必败,如果不为0,那么先手必胜

证明过程详见AcWing算法基础课数学知识(四)1:11:00

代码:

#include<iostream>
using namespace std;int main() {int n; cin >> n;int res = 0;while (n--) {int x; cin >> x;res ^= x;}if (res)cout << "Yes";else cout << "No";return 0;
}

AcWing.892.台阶-Nim游戏
现在,有一个 n n n 级台阶的楼梯,每级台阶上都有若干个石子,其中第 i i i 级台阶上有 a i a_{i} ai 个石子 ( i ≥ 1 ) (i≥1) (i1)

两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。

已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式
第一行包含整数 n n n

第二行包含 n n n 个整数,其中第 i i i 个整数表示第 i i i 级台阶上的石子数 a i a_{i} ai

输出格式
如果先手方必胜,则输出 Yes
否则,输出 No

数据范围
1 ≤ n ≤ 105 , 1≤n≤105, 1n105,
1 ≤ a i ≤ 109 1≤ai≤109 1ai109

输入样例:

3
2 1 3

输出样例:

Yes

过于抽象,可以参照详情
详细过程:AcWing算法基础课习题课week7——18:00

在分析中,我们可得知保证最优解且先手必胜的前提为能够保证每次先手操作前的时候看到的都是奇数级台阶的石子数一定是有不同的,也就是在操作后对手看到的奇数级台阶的石子数都是相同的,这样可以保证先手必胜。

故我们只需要求出奇数级台阶的石子数量的抑或值,如果为0,那么就必败,如果不为0,那么必胜。

#include<iostream>
using namespace std;int main() {int n; int res = 0;cin >> n;for (int i = 1; i <= n; i++) {int x; cin >> x;if (i % 2)res ^= x;}if (res)puts("Yes");else puts("No");return 0;
}

—————————————————————————————————————————————————

接下来是SG函数

定义Mex运算,为找到一个集合里面最小的不存在的自然数

从一个局面可以通过不同的操作衍生出很多其他的局面,比如果从一堆石子中拿一个会走向一种局面,拿两个就是另一种局面,以此类推
对于SG函数,我们首先把终点状态的SG函数值定义为0
对于过程中任意一个局面,假如现在处于 x x x局面,且 x x x局面可以衍生出 y 1 , y 2 , y 3 . . . y k y_{1},y_{2},y_{3}...y_{k} y1,y2,y3...yk等局面,那么在 x x x局面的SG函数值就等于 SG( x x x) = Mex{ SG( y y y1), SG( y y y2), SG( y y y3)…SG( y y yk) }。

比如说有一个局面指向且仅指向终点,那么他的SG函数值就只能为 1 1 1

最终对于一系列局面,起点的SG(x) = 0时,就是必败,SG(x) ≠ 0时,就是必胜

因为如果先手保证了当前SG值不为0,那么就是一定是可以到达0的,也就是说在双方绝顶聪明的前提下,一定能使得对手处于SG值等于0的局面,相反,如果先手的SG值等于0,那么就会让对手使得自己最终处于SG值等于0的局面

而且应用SG函数时,我们都会有多个图需要考虑,也就是说先手会从多个图里面选,如果所有的图都无法胜利,那么就导致最终的失败,但是如果有一个图可以胜利,那么就可以导致最终胜利

在多个图的情形下,只需要把多个图的SG的起点的值抑或起来就可以,如果最终得到结果是0,那么必败,如果不为0,那么必胜

AcWing.893.集合-Nim游戏
给定 n n n 堆石子以及一个由 k k k 个不同正整数构成的数字集合 S S S

现在有两位玩家轮流操作,每次操作可以从任意一堆石子中拿取石子,每次拿取的石子数量必须包含于集合 S S S
,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式
第一行包含整数 k k k,表示数字集合 S 中数字的个数。
第二行包含 k k k 个整数,其中第 i i i 个整数表示数字集合 S S S 中的第 i i i 个数 s s si
第三行包含整数 n n n
第四行包含 n n n 个整数,其中第 i i i 个整数表示第 i i i 堆石子的数量 h h hi

输出格式
如果先手方必胜,则输出 Yes
否则,输出 No

数据范围
1 ≤ n , k ≤ 100 , 1 ≤ s i , h i ≤ 10000 1≤n,k≤100,1≤s_{i},h_{i}≤10000 1n,k100,1si,hi10000

输入样例:

2
2 5
3
2 4 7

输出样例:

Yes

根据上述的SG函数,我们可以把每一堆石子的局面的各种选法的集合看成一个图,那么在样例中我们就有三个图,分别求出这三个图的起点的SG函数值,将其抑或起来,就可以得到最终的结果

代码:

#include<iostream>
#include<cstring>
#include<unordered_set>
using namespace std;const int N = 110;
const int M = 10010;int n, m;
int s[N],f[M];	//s:可以选的石子个数,f:SG函数值int sg(int x) {if (f[x] != -1)return f[x];	//如果某个状态算过,那么就直接返回这个状态的值unordered_set<int> S;	//哈希表存所有可以到达的值for (int i = 0; i < m; i++) {int sum = s[i];if (x >= sum)S.insert(sg(x - sum));	//如果这堆石子的数量是大于拿走的数量的//那么才能够存进去}for (int i = 0;; i++) {	//找集合中不存在的最小的自然数if (!S.count(i))	//如果这个数在S中找不到return f[x] = i;//那么就返回这个数作为其SG函数值}
}int main() {cin >> m;for (int i = 0; i < m; i++)cin >> s[i];	//能够选的石子数cin >> n;	//石子堆数memset(f, -1, sizeof f);	//初始化f数组,以进行记忆化搜索int res = 0;	//存答案for (int i = 0; i < n; i++) {int x;			//输入n堆石子各有多少个石子cin >> x;res ^= sg(x);	//对每堆石子求其SG函数值,并进行抑或操作}if (res)puts("Yes");//如果最后非0,那么必胜else puts("No");	//否则必败return 0;
}

AcWing.894.拆分-Nim游戏
给定 n n n 堆石子,两位玩家轮流操作,每次操作可以取走其中的一堆石子,然后放入两堆规模更小的石子(新堆规模可以为 0 0 0,且两个新堆的石子总数可以大于取走的那堆石子数),最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式
第一行包含整数 n n n

第二行包含 n n n 个整数,其中第 i i i 个整数表示第 i i i 堆石子的数量 a i a_{i} ai

输出格式
如果先手方必胜,则输出 Yes
否则,输出 No

数据范围
1 ≤ n , a i ≤ 100 1≤n,a_{i}≤100 1n,ai100

输入样例:

2
2 3

输出样例:

Yes

可以将n堆石子看作n个局面(集合),对于每个局面求SG值之后把他们抑或起来求结果即可

对于每个局面,我们只需要找到其所有能到的值,然后再去找不存在的最小自然数,在过程中会出现一堆分成两堆的情况,两堆的局面的SG值就等于两堆各自的SG值抑或起来

#include<iostream>
#include<unordered_set>
#include<cstring>
using namespace std;const int N = 110;int f[N];		//存sg值int sg(int x) {	//sg函数if (f[x] != -1)return f[x];	//如果已经搜过了就不用再算了unordered_set<int>S;		//哈希表存各种局面的sg值//插入两堆for (int i = 0; i < x; i++) {		//第一堆插入小于总石子数的石子for (int j = 0; j <= i; j++) {	//避免重复,使第二堆小于等于第一堆的石子数S.insert(sg(i)^sg(j));		//两堆的sg值等于两堆各自的sg值抑或起来}}for (int i = 0;; i++)	//找到集合中不存在的自然数if (!S.count(i))return f[x] = i;
}int main() {int n; cin >> n;memset(f, -1, sizeof f);int res = 0;	//答案for (int i = 0; i < n; i++) {int x; cin >> x;res ^= sg(x);	//输入每堆石子数量并抑或上它}if (res)puts("Yes");else puts("No");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/669332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超多制作模板的姓氏头像生成器微信小程序源码

超多制作模板的姓氏头像生成器微信小程序源码&#xff0c;这是一款姓氏头像制作小工具&#xff0c;内含丰富多样的模板提供制作。 以前的基本是固定位置生成&#xff0c;这款制作支持拖拽调整位置&#xff0c;自定义颜色&#xff0c;阴影等等。

探索设计模式的魅力:外观模式简化术-隐藏复杂性,提供简洁接口的设计秘密

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言&#xff1a;探索简化之路 一、起源和演变 二、场景案例分析 2.1 不用模式实现&#xff1a;用一坨坨代码实现 2.2 问题 2.3 外观模式重构代码 定义 界面 接口 利用外观模式解决问题步骤 外观模式结构和说明 重构…

Linux 网络:PTP 简介

文章目录 1. 前言2. PTP(Precision Time Protocol​) IEEE 1588 协议简介2.1 PTP IEEE 1588 协议时间同步原理2.2 PTP IEEE 1588 协议时钟类型2.2.1 普通时钟(OC: Ordinary Clock)2.2.2 边界时钟(BC: Boundary Clock)2.2.3 透明时钟(TC: Transparent Clock)2.2.3.1 端对端透明时…

OpenGL帧缓冲 Framebuffers and Framebuffer Objects

OpenGL帧缓冲区和帧缓冲区对象 Framebuffers and Framebuffer Objects 帧缓冲区的结构和组成&#xff0c;以及与默认帧缓冲区和帧缓冲对象相关的管理和属性。 帧缓冲区结构&#xff1a; 帧缓冲区由像素组成&#xff0c;排列成二维数组&#xff0c;每个像素由一定数量的位组成。…

【安防】三个问题:IPC和ITC主要的差异点和相同点 、影响图像成像效果的因素有哪些、摩尔纹如何产生的和消除方法

问题一、IPC和ITC主要的差异点和相同点 差异点 1、应用场景&#xff1a;IPC主要应用于普通安防监控领域&#xff0c;如广场、商场、公园、写字楼等。它们通常被用于监控室内或有限区域的安全&#xff0c;例如&#xff0c;监控办公室、仓库、门口等。而ITC则主要应用于交通领…

【论文研读】Better Together:Unifying Datalog and Equality Saturation

最近研究ReassociatePass整的头大&#xff0c;翻两篇Datalog的论文看看。 今天看的一篇是比较新的文章&#xff0c;23年4月贴到arxiv上的。 本文的主要贡献是提出了egglog,将Datalog和Eqsat结合起来&#xff0c;继承了Datalog的efficient incremental execution, cooperating a…

【前端web入门第四天】02 CSS三大特性+背景图

文章目录: 1. CSS三大特性 1.1继承性 1.2 层叠性 1.3 优先级 1.3.1 优先级1.3.2 优先级-叠加计算规则 2. 背景图 2.1 背景属性2.2 背景图2.3 背景图的平铺方式2.4 背景图位置2.5 背景图缩放2.6 背景图固定2.7 背景复合属性 1. CSS三大特性 1.1继承性 什么是继承性? 子级默…

前端实现搜索框筛选

效果图 页面解析 是一个input输入框和一个button按钮组成输入框查询 内容是一个折叠面板 html代码 <div class"left-content-box"><div class"colum-search"><el-input v-model"columKey" clearable placeholder"请输入关…

redis大数据统计之hyperloglog,GEO,Bitmap

目录 一、亿级系统常见的四中统计 1、聚合统计 2、排序统计 3、二值统计 4、基数统计 二、hyperloglog 去重的方式有哪些&#xff1f; hyperloglog实战演示 1、技术选型 2、代码演示 三、GEO GEO实战演示 四、Bitmap 一、亿级系统常见的四中统计 1、聚合统计 聚…

STM32F407移植OpenHarmony笔记7

继上一篇笔记&#xff0c;成功启动了liteos_m内核&#xff0c;可以创建线程了&#xff0c;也能看到shell控制台了。 今天研究文件系统&#xff0c;让控制台相关文件命令如mkdir和ls能工作。 liteos_m内核支持fatfs和littlefs两个文件系统&#xff0c; fatfs适用于SD卡&#xff…

将11.x.x升级至16.x.x不成功的一系列问题(二)node-sass sass-loader需安装指定版本

nvm 版本切换搞定了 咱就是说 那个node-sass好像有点毛病 还得指定对应的loaber版本 node.js 16.18.1对应的如下 “node-sass”: “^6.0.1”, “sass-loader”: “^10.0.1”, node.js 11.8.0 对应的如下 “node-sass”: “^4.14.1”, “sass-loader”: “^7.3.1”, 老项目即…

linux+rv1126/imx6ull:opencv静态库交叉编译(手把手百分百成功)

目录 1.下载 2.准备工作 2.1安装依赖环境 2.2安装Cmake 2.3 解压opencv 3.Cmake设置

python-题库篇-数学

文章目录 求最大公约数和最小公倍数斐波那契数列求和运算求前n阶乘的和求年龄 求最大公约数和最小公倍数 两个数的最大公约数是两个数的公共因子中最大的那个数&#xff1b;两个数的最小公倍数 则是能够同时被两个数整除的最小的那个数。 输入&#xff1a;&#xff08;120 和…

零基础如何入门渗透测试2024年最新版,保姆级教程,小白必看!

转眼间&#xff0c;从大三开始学安全&#xff0c;到现在也有五年了&#xff0c;也算是对渗透测试有一定理解&#xff0c;今天也是出一篇入门教程&#xff0c;以实操为主&#xff0c;希望可以帮助到想入门渗透测试的小白。如果觉得有用&#xff0c;可以给我点个赞和收藏&#xf…

Android: 深入理解 ‘companion object {}‘

Android: 深入理解 ‘companion object {}’ Kotlin是一种现代的、静态类型的编程语言&#xff0c;它在设计时充分考虑了开发者的生产力和代码的可读性。其中一个独特的特性就是companion object。在本篇博客中&#xff0c;我们将深入探讨这个特性&#xff0c;理解它的工作原理…

DBA不仅仅是管理数据库--也要管理中间件

看到这个标题可能觉得我在乱说&#xff0c;其实很多中间件作为数据库的上下游&#xff0c;它们的稳定取决于数据库的稳定。这里我主要指的是SQL。 很早之前我说开发的主题语言其实更多的是SQL&#xff08;这里并没有说Java不重要的意思&#xff09;&#xff0c;只是Java中并没有…

Java21 + SpringBoot3集成七牛云对象存储OSS,实现文件上传

文章目录 前言实现步骤引入maven依赖修改配置文件创建七牛云配置类创建文件操作服务类创建文件操作控制器前端实现运行效果 总结 前言 近日心血来潮想做一个开源项目&#xff0c;目标是做一款可以适配多端、功能完备的模板工程&#xff0c;包含后台管理系统和前台系统&#xf…

EOF和0区别

题目描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的X形图案。 输入描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜…

你的歌声婉转入云霄

可爱的一朵玫瑰花 - 吕继宏 可爱的一朵玫瑰花塞地玛丽亚 可爱的一朵玫瑰花塞地玛丽亚 那天我在山上打猎骑着马&#xff08;人善被人欺马善被人骑&#xff09; 正当你在山下歌唱婉转入云霄 歌声使我迷了路 我从山坡滚下 哎呀呀 你的歌声婉转入云霄 强壮的青年哈萨克伊万杜达尔 …

【八大排序】选择排序 | 堆排序 + 图文详解!!

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C语言进阶之路 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 一、选择排序1.1 基本思想1.2 算法步骤 动图演示1.3 代码实现1.4 选择排序特性总结 二…