Nim游戏在ACM中碰到了,就拎出来写写。
一般Nim游戏:有n堆石子,每堆石子有$a_i$个,每次可以取每堆石子中$[0,a_i-1]$,问先手是否有必胜策略。
泛Nim游戏:每堆石子有$a_i$个,每次可以取每堆石子中若干个且有一定限制,问先手是否有必胜策略。
我们定义 :
P 表示 先手必败局
N 表示 后手必败局
性质1:对于Nim游戏任何局面要么是P要么是N。
给出 N P 状态的严谨定义(性质) :
1. 无法更改局面的局面是 P
2. 可移动到 P 的是 N
3. 所有移动都导致 N 的是 P
根据上述定义,我们可以知道,如何判定一个局面是P,
就是枚举它的所有移动,若全部后继状态都会移动到 N 那么就是 P
性质2:对于一般的Nim游戏,若存在$ \{a1,a2...an \} $的局面,那么
若$ a_1 \oplus a_2 \oplus ... \oplus a_n = 0 $那么是 P ; 否则是 N 。
对此我们只需要证明以下三个引理,就可以推出全部情况:
引理1:所有无法移动的局面都是P
引理2:若一个局面是$ \{a1,a2...an\} $,且 $ a_1 \oplus a_2 \oplus ... \oplus a_n \neq 0 $
那么必然可以把某个 $ a_i $ 改成 $ a_i'$ 让 $ a_1 \oplus a_2 \oplus ...a_i'... \oplus a_n = 0 $
证明 : 设$ a_1 \oplus a_2 \oplus ... \oplus a_n \neq 0 = k > 0 $
那么显然有奇数个$a_i$满足二进制表示最高位是 1 ,取其中一个最高位是 1 的 $a_i$ 改成 $ a_i=a_i \oplus k $
那么此时 , $ a1 \oplus a2… \oplus ai' \oplus ...an=a1 \oplus a2… \oplus ai \oplus k \oplus ...an=k \oplus k=0 $
显然$ a_i \oplus k (k \neq 0) < a_i $(至少消去最高位的1)成立,证毕。
引理3:若一个局面是$\{a1,a2...an\} $,且$ a1 \oplus a2...an=0 $,那么不存在某种合法引动改变任何一个数字$ ai=ai' (ai'<ai) $使得$ a1 \oplus a2… \oplus ai' \oplus ...an=0$
证明:已知$ a1 \oplus a2... \oplus ai...an=0 $且$ a1 \oplus a2… \oplus ai' \oplus ...an=0 $,把式子左右两边异或起来,由异或的消去律可知。
$ ai \oplus ai'=0 $ , 所以 必然的$ ai=ai' $,和 $ ai'<ai $ 矛盾。
证毕。
由于三个引理成立,那么性质2成立。
关于一般的 Impartial Combinatorial Games 的模型 :
Sprague-Garundy 函数
一般模型:一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负。
任何一个ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”。
我们定义mex{}表示集合中最小的没有出现过的非负整数。
mex{0,1,2,4}=3 , mex{0}=0等。
$sg(x) = mex \{ sg(y) | y是x的后继 \} $,可以理解为$ sg(x) $表示$x$所在子树节点y中$sg(y)$最小没有出现过的非负整数。
考察SG函数的性质:
1. 图上没有出边的点$ sg=0 $,因为后续集合都是空集。
2. 若一个$ sg(x)=0$的顶点,所有后继$y$满足$ sg(y)\neq 0$
3. 若一个$ sg(x)\neq 0$的顶点,必然存在一个后继$y$满足$sg(y)=0$
我们假设每个顶点都是一个决策,那么对于$x$节点的决策,若是P那么$sg(x)=0$,若是N那么$sg(x)\neq 0$
若扩展这个模型,把原来1颗棋子换成n颗棋子,由$ sg(x) $的定义可知
性质3: 当$ sg(x)=k $时,对于任意$i$满足$ i \in [0,k)$都存在一个$ y $ 是$ x $的后继满足$ sg(y)=i $ (根据sg的性质显然),不存在一个$y$满足$sg(y)=k$
考虑$sg(x)$和Nim原版游戏的相似处:Nim原版游戏是对于一堆棋子有$k$个,可以变成$[0,k-1]$,不能变成$k$个,不存在一个后继状态又取这堆棋子又这堆棋子一个不取。
至此, 我们已经把$sg(x)$和Nim游戏建立起高度等价的关系,$sg(x)$满足所有Nim游戏a数组的性质。
如果我们的有向图上问题是由多个Nim游戏拼接起来的,那么我们依然可以使用Nim游戏的思想来解决问题。
设$ G_1,G_2,G_3...G_n$是若干个有向图游戏,显然,对于每个$G_i$都满足Nim游戏的性质,若$n$个棋子在同一个有向图中移动的情况已经考虑过了
若$ n $个棋子不在同一个有向图中,我们可以看做,每次选择一个棋子所在的有向图进行移动,不会对答案有任何影响。
性质4: 即$ SG(G)=sg(G_1) \oplus sg(G_2)...sg(G_n)$
对于所有博弈论的题目,我们只需要:
1 . 把原问题分解成几个独立的子问题,利用性质4,求出全局$ SG(G)=sg(G_1) \oplus sg(G_2)...sg(G_n)$
2 . 考虑设计一个子游戏,计算SG值,
0x01:可选步数为任意步的时候$ sg(x)=x $
0x02:可选步数为$ [1,m] $步的时候$sg(x)=x\% (m+1)$
0x03: 满足一些奇怪的性质的sg函数。
给出Nim游戏打表求SG的模板:
define MAX
/* 计算从1-n范围内的SG值。
Array(存储可以走的步数,Array[0]表示可以有多少种走法)
Array[]需要从小到大排序
*/
int SG[MAX], hash[MAX];
void GetSG(int Array[],int n = MAX-)
{
memset(SG, , sizeof(SG));
for(int i = ; i <= n; ++i)
{
memset(hash, , sizeof(hash));
for(int j = ; j <= Array[]; ++j)
{
if(i < Array[j])
break;
hash[SG[i - Array[j]]] = ;
}
for(int j = ; j <= n; ++j)
if(!hash[j])
{
SG[i] = j;
break;
}
}
}
非递归求SG
//注意 S数组要按从小到大排序表示某一堆有走法可能 SG函数要初始化为-1 对于每个集合只需初始化1遍
//n是集合s的大小 S[i]是定义的特殊取法规则的数组
int s[],sg[],n;
int SG_dfs(int x)
{
int i;
if(sg[x]!=-)
return sg[x];
bool vis[];
memset(vis,,sizeof(vis));
for(i=;i<n;i++)
{
if(x>=s[i])
{
SG_dfs(x-s[i]);
vis[sg[x-s[i]]]=;
}
}
int e;
for(i=;;i++)
if(!vis[i])
{
e=i;
break;
}
return sg[x]=e;
}
递归求SG
【博弈论】浅谈泛Nim游戏的更多相关文章
-
浅谈公平组合游戏IGC
浅谈公平组合游戏IGC IGC简介 一个游戏满足以下条件时被叫做IGC游戏 (前面三个字是自己YY的,不必在意) 竞争性:两名玩家交替行动. 公平性:游戏进程的任意时刻,可以执行的操作和操作者本人无关 ...
-
(博弈论)51NOD 1069 Nim游戏
有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N及每堆石子的数量,问最后 ...
-
今日文摘:浅谈 HTML5 的游戏化之路
如今商业网站中用于广泛的HTML5无限下拉效果已经越来越受到游戏网站的喜爱.各个品牌为了打造专属自己的游戏特色,纷纷推出了模拟HTML5效果的品牌 站,且都起到了相当好的效果.可是从很多方面来说我们对 ...
-
浅谈LZSS与游戏图片破解
业余游戏制作者最头疼的就是没有美工的支持了.很多业余游戏制作所使用的图片都是来自于网上的很有限的一些图片资源,然而这些图片并不能完整配套,所以业余游戏的画面往往显得单调或者搭配不协调(使用多个不属 ...
-
BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论
BZOJ_3105_[cqoi2013]新Nim游戏_线性基+博弈论 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作 ...
-
浅谈博弈论中的两个基本模型——Bash Game&;&;Nim Game
最近在数学这一块搞了蛮多题目,已经解决了数论基础,线性代数(只有矩阵,行列式待坑),组合数学中的一些简单问题.所以接下来不可避免的对博弈论这一哲学大坑开工. 当然,由于我很菜,所以也只能从最基础最容易 ...
-
浅谈博弈论之Nim初步(xor正确性的浅显证明)
引入 在许多地方曾流行过这样一个小游戏:摆出三堆硬币,分别包含3枚,5枚,7枚.两人轮流行动,每次可任选一堆,从中取走任意多枚硬币,可把一堆取光,但不能不取,取走最后一枚硬币者获胜. 概念 \(先手: ...
-
透过Nim游戏浅谈博弈
452. Nim游戏! ★ 输入文件:nim!.in 输出文件:nim!.out 简单对比时间限制:1 s 内存限制:128 MB 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是 ...
-
BZOJ_1022_[SHOI2008]_小约翰的游戏John_(博弈论_反Nim游戏)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1022 反Nim游戏裸题.详见论文<组合游戏略述——浅谈SG游戏的若干拓展及变形>. ...
随机推荐
-
CountDownLatch和CyclicBarrier 举例详解
有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始.举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个 ...
-
perl基本语法--转载
http://www.cnblogs.com/zhtxwd/archive/2012/03/06/2381585.html 本文介绍从变量类型.操作运算符.控制叙述.子程序.I/O和档案处理. Reg ...
-
Leetcode#68 Text Justification
原题地址 没有复杂的算法,纯粹的模拟题 先试探,计算出一行能放几个单词 然后计算出单词之间有几个空格,注意,如果空格总长度无法整除空格数,前面的空格长度通通+1 最后放单词.放空格,组成一行,加入结果 ...
-
Hibernate 缓存机制二(转)
感谢:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...
-
HTML解析利器 - HtmlAgilityPack
HtmlAgilityPack 是CodePlex 上的一个开源项目.它提供了标准的DOM API 和XPath 导航--即使 HTML 不是适当的格式! 使用HtmlAgilityPack操作HTM ...
-
要点Java17 String
字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串. 创建字符串 创建字符串最简单的方式例如以下: String greeting = &quo ...
-
hive sql常用整理-hive引擎设置
遇到个情况,跑hive级联insert数据报错,可以尝试换个hive计算引擎 hive遇到FAILED: Execution Error, return code 2 from org.apache. ...
-
JWT(Json Web Token—)的定义及组成
JWT定义及其组成 JWT(JSON Web Token)是一个非常轻巧的规范.这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息. 一个JWT实际上就是一个字符串,它由三部分组成,头部. ...
-
Linux系统服务(daemon)(鸟哥Linux私房菜笔记)
Linux系统服务(daemon) 一.SystemV的init管理机制(脚本式启动)1.服务启动分类stand alone 独立启动模式super daemon 总管程序 2.服务的启动.关闭与观察 ...
-
cassandra 之 在spark-shell 中使用 spark cassandra connector 完整案例
1.cassandra 准备 启动cqlsh, CQLSH_HOST=172.16.163.131 bin/cqlsh cqlsh>CREATE KEYSPACE productlogs WIT ...