引例Nim游戏:
有三堆扑克牌(比如:可以分别是 5,7,9张);
游戏双方轮流操作;
有两个玩家;
玩家的每次操作是选择其中某一堆牌,然后从中取走任意张;
最后一次取牌的一方为获胜方;
可以推出:对于nim游戏的某个位置(x1,x2,x3),当且仅当它各部分的nim-sum等于0时(即x1⊕x2⊕x3=0),则当前位于必败点。
博弈里面常常用到一个重要的概念 -- SG。书上的定义:除任意一步所能转移到的子局面的SG值以外的最小非负整数。
SG函数
首先定义mex(minimal excludant)运算
这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数
例如mex{0,1,2,4}=3,mex{2,3,5}=0,mex{}=0
对于任意状态xx, 定义 SG(x)=mex(S)SG(x)=mex(S),其中SS是xx后继状态的SG函数值的集合
如xx有三个后继状态分别为SG(a),SG(b),SG(c)SG(a),SG(b),SG(c),那么SG(x)=mex(SG(a),SG(b),SG(c))SG(x)=mex(SG(a),SG(b),SG(c))
SGSG函数的终态为SG(x)=0SG(x)=0,当且仅当xx为必败点时
Sprague-Grundy定理(SG定理)
游戏和的SGSG函数等于各个游戏SGSG函数的NimNim和
这样就可以将每一个子游戏分而治之,从而简化了问题
而BoutonBouton定理就是Sprague−GrundySprague−Grundy定理在NimNim游戏中的直接应用,因为单堆的NimNim游戏SGSG函数满足 SG(x)=x
SG的解题:
解题模型:
1.把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或。
即sg(G)=sg(G1)^sg(G2)^...^sg(Gn)。
2.分别考虑没一个子游戏,计算其SG值。
SG值的计算方法:(重点)
1.可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);
2.可选步数为任意步,SG(x) = x;
3.可选步数为一系列不连续的数,用模板计算。
SG基本能解决大部分题,模式一般有打表,DP,DFS。学会SG,博弈不成问题。
HDU 1847Good Luck in CET-4 Everybody!
POJ 2425 A Chess Game
ZOJ 3529
但愿看到Aliceand Bob,我都能说这题我来。