[算法] 2-4 组合游戏
1、Nim游戏:有3堆火柴,分别为a,b,c根,记为状态(a,b,c)。每次一个游戏者可以从任意一堆中拿走至少一根火柴,也可以整堆拿走,但不能从多堆火柴中同时拿走。无法拿火柴的游戏者输。
2、组合游戏:Nim游戏其实就是组合游戏的一种,它满足:
a\两个游戏者轮流操作
b\游戏状态有限。并且不管双方怎么走,都不会出现以前出现过的状态。
c\谁不能操作谁输,另一个获胜。
3、状态图:为了方便分析,我们可以把游戏中的状态画成图。每个节点是一个状态,每条边代表从一个状态转移到另一个状态的操作(我们只讨论公平游戏,即:一个游戏者可以把状态A变为状态B,另一个游戏者也可以。)
4、两条规则:
a\一个状态必败当且仅当它所有的后继都是必胜状态。
b\一个状态必胜当且仅当它的后继有一个是必败状态。
*\特别的:没有后继的状态是必败状态。
有了这两条规则,就可以用递推的方法判断整个图的每一个结点是必胜态还是必败态。(注意到状态图都是无环的,所以如果按照拓扑排序的逆序进行判断,在判断每个节点的时候,他的所有后继都已经判断过啦。)
5、举个例子:
a\Ferguson游戏:有2个盒子,一开始其中一个有m颗糖而另一个有n颗糖,即状态(m,n)。每次操作是将一个盒子清空而把另一个盒子的一些糖拿到被清空的盒子中,使得2个盒子至少各有1颗糖。显然唯一的终止态为(1,1)。如果最后移动的游戏者获胜,那么状态为(m,n)的先手胜还是败?||-><-||根据第四点的规律我们按照k=m+n从小到大的顺序判断即可。下面代码输出所有k<20的必败态,由于(m,n)和(n,m)等价,这里只输出了n<=m的必败态。
1 #include<iostream> 2 using namespace std; 3 4 const int maxn = 100; 5 int winning[maxn][maxn]; 6 int main(){ 7 winning[1][1]=false; 8 for(int k=3;k<20;k++){//k由小到大枚举 9 for(int n=1;n<k;n++){//对于每个k枚举n 10 int m=k-n;//计算出状态k时的对应m 11 winning[n][m]=false;//先默认为输 12 for(int i=1;i<n;i++)//分析winning[n][m]后继之m倒掉 13 if(!winning[i][n-i]){winning[n][m]=true;break;} 14 for(int i=1;i<m;i++)//分析winning[n][m]后继之n倒掉 15 if(!winning[i][m-i]){winning[n][m]=true;break;} 16 if(n<=m && !winning[n][m])cout<<n<<' '<<m<<'\n'; 17 } 18 }return 0; 19 }
View Code
6、Nim sum:如果用上面相同的方法逆向判断所有节点,当a,b,c很大时,计算复杂度将会很高。其实早在1902年L.Bouton就提出了这样一个定理:状态(a,b,c)为必败态当且仅当a^b^c=0,这里的操作是二进制逐位异或操作(相同为0,不同为1),也成为Nim和(Nim sum)。
7、组合游戏的和:
a\定义:假设有k个组合游戏G1,G2,……,Gk,可以定义一个新游戏,在每个回合中,当前游戏者可以任选一个子游戏Gi进行一次合法操作,让其他游戏的局面保持不变,不能操作的游戏者输。这个新游戏称为G1,G2,……,Gk的和。
b\Nim:这样Nim游戏其实就是3个组合游戏G(从一堆火柴中拿走至少一根也可整堆拿走,无法拿的输)的和。为什么呢?因为每个回合里,当前游戏者可以选择一个子游戏(即选一堆火柴),然后进行一次合法操作(从该堆中拿火柴),但其他子游戏的局面保持不变(不能从多堆火柴中同时拿)。
c\SG定理和SG函数:组合游戏的和通常是很复杂滴,但是可以利用SG函数和SG定理来解决问题。||-><-||对于任意状态x,定义SG(x)=mes(S),其中S={SG(y)|y是x的后继状态},mex(S)表示不在S内的最小自然数。这样终态的SG值显然为0(S为空),而其他值可以递推出来,不难发现SG(x)=0当且仅当x为必败态。
8、类似Nim的游戏:
a\翻棋子游戏:一个棋盘上每个格子有一个棋子,每次操作可以随便选一个朝上的棋子(x,y)(代表x行y列),选一个形如(x,b)或者(a,y)(其中b<y,a<x)的棋子,然后把它和(x,y)一起旋转,无法操作的人输。||-><-||把坐标为(x,y)的棋子看做是大小分别为x,y的2堆火柴,每次操作是把其中一堆的数量减少或删除。
b\除法游戏:有一个n x m (1<=n,m<=50)矩阵,每个元素均为2-10000之间的正整数。两个游戏者轮流操作。每次可以选中一行中的1个或者多个大于1的整数,把他们中的每个数都变为它的某个素因子,比如:12可以变为1,2,3,4,6,不能操作的输(即:在操作之前矩阵全是1则输)。||-><-||考虑每个数的素因子个数,则让一个数“变为它的真因子”等价于拿掉它的一个或多个素因子。这样,每行对应一个火柴堆,每个数的每个素因子看成一根火柴,则本题和Nim完全等价啦。
[算法] 2-4 组合游戏相关推荐
- (组合游戏)SG函数与SG定理详解
文章目录 前言 什么是组合游戏 必胜点和必败点的概念 Sprague-Grundy(SG)定理 SG函数 前言 好久没写博客了,上一篇博客还是去年实训写的,一是因为寒假,二是因为随着难度的加深,学 ...
- 博弈论 1.Introduction(组合游戏基本概念、对抗搜索、Bash游戏、Nim游戏)
1.博弈 博弈论是研究具有斗争或竞争性质现象的数学理论和方法. 每个玩家都有一个偏好,A一般是希望A赢,如果不可以的话就倾向于 平局,B一般倾向B赢,达不到的话就倾向于平局.他们的每一步组成了一个&q ...
- 博弈论·公平组合游戏 学习笔记
文章目录 公平组合游戏ICG N状态和P状态 游戏图 Sprague-Grundy SG函数 Nim游戏 游戏的和 SG定理 写在前面:发现是好久之前存在草稿里的,偶然间翻出来了,稍微完善了一下. 公 ...
- 博弈论——公平组合游戏与SG函数
参考自算法竞赛进阶指南 公平组合游戏与有向无环图 一个博弈游戏被称为公平组合游戏(ICG)当且仅当其同时满足3个条件 由两名玩家交替行动 游戏任意时刻可进行的操作与轮到哪名玩家无关 不能进行操作的玩家 ...
- 求n个数中第k大的数_互联网高频面试题目:「回溯算法」求组合总和
我将算法学习相关的资料已经整理到了Github :https://github.com/youngyangyang04/leetcode-master,里面还有leetcode刷题攻略.各个类型经典题 ...
- ML之SVM:利用SVM算法(超参数组合进行多线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测、评估
ML之SVM:利用SVM算法(超参数组合进行多线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测.评估 目录 输出结果 设计思路 核心代码 输出结果 Fitting 3 folds for ...
- ML之SVM:利用SVM算法(超参数组合进行单线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测、评估
ML之SVM:利用SVM算法(超参数组合进行单线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测.评估 目录 输出结果 设计思路 核心代码 输出结果 Fitting 3 folds for ...
- 本题要求实现一个求整数的逆序数的简单函数。_回溯算法:求组合总和(二)...
给「代码随想录」一个星标吧! ❝ 我将公众号文章和学习相关的资料整理到了Github :https://github.com/youngyangyang04/leetcode-master,方便大家在 ...
- 算法实现自动扫雷游戏
算法实现自动扫雷游戏 1.游戏的构思 2.算法伪代码的实现 3.算法的实现 1.首先需要建立起游戏的整个框架(棋盘的绘制,地雷的生成,基本函数的实现等) 2.构思AI算法的大概样貌(先尝试写伪码) v ...
最新文章
- 《人民日报》发声:科研人员收入理应体现他们的价值
- PyTorch学习笔记——pytorch图像处理(transforms)
- 11g 64位部分安装过程
- python3.10_概述 — Python 3.10.0a2 文档
- 【原创】指针和下标的10条对比
- python supervisor flask_supervisor配合uwsgi部署flask应用
- Fedex Ship Manager Software安装
- 【转载】程序员历史之一
- 晨哥真有料丨盘点追女生的作死行为!
- 关闭MySQL日志,删除mysql-bin.0000*日志文件
- Java命令学习系列(六)——javap
- Intel(R) Matrix Storage Manager 介绍
- 数据库索引的概念和分类
- 图像标注工具labelImg使用
- 使用MybatisPlus实现ShiroRealm
- ArcGIS转CAD坐标
- 使用 RGL 制作交互式 3D 散点图
- 微信引流黑科技:手机浏览器直接唤起微信方案调研
- 织梦dedecms蓝色商务学院职业技术学校网站模板
- excel去掉公式()
热门文章
- 常用邮箱申请渠道有哪些?此文给你讲清楚了
- 论大型信息系统集成项目的整体管理
- spark python3.6_在mac上搭建spark+ipython环境
- mvc ajax提交多选,javascript – 如何使用Jquery AJAX调用MVC Action然后在MVC中提交表单?...
- python语音引擎深度学习_python深度学习之语音识别(speech recognize)
- 直播预告丨爆款独立站如何利用数据提升经营效率?
- 洛谷 P2048 [NOI2010]超级钢琴(优先队列,RMQ)
- Linux 批量修改文件名
- hdu1174(3维射线与圆是否相交)
- Checkstyle 简介 以及各版本下载地址