最近手贱,又整acm的东西了。。。
说到博弈论,就想起了Alice和Bob。比如Sicily 1798. Alice and Bob
之前做过一些题,可以构造出必胜的走法,需要技巧,遇到复杂一点的游戏规则就没辙了,所以还是得系统学一下一些博弈问题的解法。看到有人提起SG函数,赶紧按图索骥,g一下,找些资料。
//文绉绉的定义,随便看看就好
Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatori Games”(以下简称 ICG)。满足以下条件的游戏是ICG(可能不太严谨):
1、有两名选手;
2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;
3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素;
4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。根据这个定义,很多日常的游戏并非 ICG。例如象棋就不满
足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。
定义:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。
当然,特殊情况就是只有一堆或者两堆石子,自己去意淫一下吧。
其中P 代表Previous,N 代表Next。 P-position是必败态,N-position是必胜态。
必败(必胜)点属性
(1) 所有终结点是必败点(P点); //容易理解
(2) 从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点); //就是那种我们要走的方法
(3)无论如何操作, 从必败点(P点)都只能进入必胜点(N点). //对手走完又只能把N留给我们
取子游戏算法实现
步骤1:将所有终结位置标记为必败点(P点);
步骤2: 将所有一步操作能进入必败点(P点)的位置标记为必胜点(N点)
步骤3:如果从某个点开始的所有一步操作都只能进入必胜点(N点) ,则将该点标记为必败点(P点) ;
步骤4: 如果在步骤3未能找到新的必败(P点),则算法终止;否则,返回到步骤2
/*
上面的说法似乎不太好理解。我简单讲下。显然我们可以从终结条件递推回来。往后往前开始扫描,(终结状态方向为后)
a.如果当前是P点,那么一步(向前)可以走到的都是N点
b.如果当前点未标明P/N属性,那么看看该点向后走是不是都只能到达N点,如果是,那么该点是P点。
c.如果该点是N点,倒无法确定什么。
如果没办法标一个点,那么异常结束。
*/
我是用P N状态递推出来小规模的数据后找规律的,直接递推提交爆内存。(x,y)中,x和y都是奇数的话,那么无论怎么移动,x和y中都有至少有一个偶数,而且再移动一步后,都可以变成xy全奇数。
直接说结论好了。(Bouton's Theorem)对于一个Nim游戏的局面(a1,a2,...,an),
它是P-position 当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算。
根据定义,证明一种判断position的性质的方法的正确性,只需证明三个命题:
1、这个判断将所有terminal position 判为P-position;
2、根据这个判断被判为N-position 的局面一定可以移动到某个 P-position;
3、根据这个判断被判为 P-position 的局面无法移动到某个P-position。
第一个命题显然,terminal position 只有一个,就是全 0,异或仍然是0。
第二个命题,对于某个局面(a1,a2,...,an),若 a1^a2^...^an!=0,一定存在某个合法的移动,将ai 改变成 ai'后满足 a1^a2^...^ai'^...^an=0。不妨设 a1^a2^...^an=k,则一定存在某个 ai,它的二进制表示在k的最高位上是 1(否则k 的最高位那个 1是怎么得到的)。这时ai^k<ai一定成立。则我们可以将 ai改变成ai'=ai^k,此时a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
//注意可以拿走若干颗,数目不限哦
第三个命题,对于某个局面(a1,a2,...,an),若 a1^a2^...^an=0,一定不存在某个合法的移动,将 ai 改 变 成 ai' 后满足 a1^a2^...^ai'^...^an=0 。 因 为 异 或 运 算 满 足 消 去 率 , 由a1^a2^...^an=a1^a2^...^ai'^...^an 可以得到 ai=ai'。所以将 ai 改变成 ai'不是一个合法的移动。证毕。
// 简单理解,异或2次可以翻转回来,我们只改一个数字的话,翻不回来。
Being a Good Boy in Spring Festival
求Nim-Sum,非零才能赢。然后每次从Nim-Sum去掉一堆扑克牌,结果是否小于这堆扑克牌数,如果能,方法数+1
ZOJ 3529 A Game Between Alice and Bob
上面强调了一点,游戏中每次拿走的石头数目是不限的,而这道题需要运用技巧进行转换。
求出因子数即可!可以用dp,然后在筛素数的时候顺便记录一下其中一个最大的因子。源码可以看这里:
http://growthinking.com/archives/1777
现在我们来研究一个看上去似乎更为一般的游戏:给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负。事实上,这个游戏可以认为是所有 Impartial Combinatorial Games 的抽象模型。也就是说,任何一个 ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个“有向图游戏”。下面我们就在有向无环图的顶点上定义 Sprague-Garundy函数。
mex(minimal excludant)运算
定义表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。
对于一个给定的有向无环图,定义关于图的每个顶点的 Sprague-Garundy 函数 g 如下:
g(x)=mex{ g(y) | y是 x的后继 }。
来看一下 SG 函数的性质。首先,所有的 terminal position 所对应的顶点,也就是没有出边的顶点,其 SG 值为 0,因为它的后继集合是空集。然后对于一个g(x)=0 的顶点 x,它的所后继y都满足 g(y)!=0。对于一个g(x)!=0的顶点,必定存在一个后继 y满足g(y)=0。
以上这三句话表明,顶点 x 所代表的 postion 是 P-position 当且仅当 g(x)=0(跟P-positioin/N-position 的定义的那三句话是完全对应的)。我们通过计算有向无环图的每个顶点,就可以对每种局面找到必胜策略了。
sg函数小试牛刀,哈哈
一堆石子的游戏 ---->两堆石子的游戏 ---> Nim游戏 ---> 有向图
P/N position <----> Nim-Sum <----> SG函数 //想起一个词 "同构"
Nim和SG函数 博弈 http://download.csdn.net/detail/lhb807949392/3500177
HDU 组合博弈入门(或者直接搜整套课件) http://acm.hdu.edu.cn/forum/read.php?tid=6875