转载自:http://blog.csdn.net/qq_30241305/article/details/50819784
sg函数(个人认为还是用于三种方法都无法解决的情况,如按特殊数字取石子)
我们把整个博弈过程抽象为有向无环图
1. 几项准备工作:
mex求最小非负整数mex{} = 0,mex{0,1,2,4} = 3,mex{1,2,4} = 0
sg[x] =mex{sg[y]|y是x的后继}//就是石头变少的继
这样sg就满足几个性质
1. sg[x] == 0时,它的后继都不为零
2. sg[x] != 0时,它的后继一定有为零的
3. 当x点没有出边时,sg[x] == 0
这三个性质恰好与P-positon(先手必败)的性质相同:
(1).无法进行任何移动的局面(也就是terminal position)是P-position;
(2).可以移动到P-position的局面是N-position;
(3).所有移动都导致N-position的局面是P-position。
由此可知:sg[x] == 0,x就是p-position
2.
对于从一堆n个石块中取石块的过程,每次取法有一定特色(比如说按照菲薄纳切数列来去)只需求出sg[x]就可以判断了
对于从m堆石块中取石块的过程,每次取法是特殊的。只需将所有s[n]亦或就是结果
让我们再来考虑一下顶点的SG值的意义。当g(x)=k时,表明对于任意一个0<=i<k,都存在x的一个后继y满足g(y)=i。也就是说,当某枚棋子的SG值是k时,我们可以把它变成0、变成1、……、变成k-1,但绝对不能保持k不变。不知道你能不能根据这个联想到Nim游戏,Nim游戏的规则就是:每次选择一堆数量为k的石子,可以把它变成0、变成1、……、变成k-1,但绝对不能保持k不变。这表明,如果将n枚棋子所在的顶点的SG值看作n堆相应数量的石子,那么这个Nim游戏的每个必胜策略都对应于原来这n枚棋子的必胜策略!
假设一堆石块有n个石块这就意味着sg[n]确实等价为从n个石块中每次至少取一个石头
4.模板.注意要根据题目的要求初始化a[i]。切记初始化sg都为-1,init中的a一定是从小到大的
实践证明暴搜比打表快。因为暴搜得到的值,不用也不应该清空。下一次可以根据上一次暴搜得到的值进行处理
1.dfs递归版。从n个石头开始递归
调用方式:SG(n)
2. 打表法
调用方法:sg[n]