首页 > 技术文章 > SG函数

GerynOhenz 2015-04-01 22:05 原文

作为博弈论的重要算法:

SG函数

Sprague-Grundy

一定要重点学习一下下(搞到我市选的时候崩了一题,泪奔~~~)
学习SG函数之前,先要知道Nim游戏
Nim游戏:两人对战,轮流操作,每次操作与人无关(就是A能做的,B也能做),当某方无法操作时,则该方败。
经典的Nim游戏有捡石子游戏:给出N堆石子,每次选择一堆石子,取走任意个,不可不取,不能继续操作的输。
经典的非Nim游戏有象棋:双方都不可以动对方的棋。

Nim游戏主要问题是:先手是否有必胜策略。
解决这个问题先定义游戏中的两种局面:P-positionN-position
P-position:上一次移动的人有必胜策略
N-position:现在移动的人优必胜策略
那么Nim游戏满足一下几个要求:
1、所有的最终局面(terminal—position)都是P-position
2、所有的N-position都可以移动到一个P-position
3、所有的P-position都不能移动到一个P-position

那么就可以判断一种局面是否是P-position

关键是判断条件

先给出判断条件吧:
对于一个Nim游戏局面\(( a_{1}, a_{2}, ... , a_{n} )\),它是P-position当且仅当\(a_{1}\bigoplus a_{2}\bigoplus a_{3}...a_{n} =0 (\bigoplus \text 是异或号)\)

证明

1、对于terminal—position,异或和肯定是0,即是P-position,满足。
2、设该局面的异或和为K,K的最高位为D。那么有一个数在二进制下第D位肯定是1,姑且设其为\(a_{x}\),令\(a_{x}' =a_{x}\bigoplus k\),则 \(a_{x}' < a_{x}\)
$\because a_{1}\bigoplus a_{2}...a_{x}...\bigoplus a_{n} =K \( \)\therefore a_{1}\bigoplus a_{2}...a_{x}' ...\bigoplus a_{n} =0\( \)\because a_{x}' < a_{x} \( \)\therefore \text 该操作可行\( 3、反证:设局面\)a_{1}\bigoplus a_{2}...a_{x}...\bigoplus a_{n} =0 \( 下一步局面为\)a_{1}\bigoplus a_{2}...a_{x}' ...\bigoplus a_{n} =0 \( 则两式相等,因为异或运算满足消去律,所以\)a_{x}' =a_{x}$
该操作不可行。
证毕。

所以直接把初始局面的异或和求出来就可以判断是否有必胜策略。

重点来了

每一堆可以取的数目不一样怎么办???

SG函数来拯救你!!!

题目描述:有n堆石子,第i堆石子每次只能拿\([1,i]\),问先手是否有必胜策略。
因为每堆石子可以取的个数不一样,所以难以判断一个操作是否可行,也就说不能用上面的证明。
但可以利用SG函数来转化成普通的Nim游戏
先定义一个操作mex(minimal excludant)为集合运算,表示最小的不属于该集合的最小非负整数。例如\(mex\) { \(0, 1, 5\) } $ = 2\(,\)mex$ { \(1, 2, 5\) } \(= 0\)
\(SG[x]=mex\) { \(SG[y] | \text y是x的后继\) }
1、对于terminal-position,因为没有后继,所以\(SG=0\)
2、对于一个\(SG \neq 0\)的点,一定有一个后继的\(SG=0\)
3、对于一个\(SG = 0\)的点,一定没有一个后继的\(SG=0\)
4、一个点均可到达\([1,SG-1]\)的后继

咦~,怎么这么熟悉的

SG函数满足普通Nim游戏

所以只要把原来每一堆的个数变成SG函数所对应的值就可以了!!!

现在问题来了,SG函数怎么得到

我也只能说:打表找规律吧。
不过上述题目应该很容易就可以求出SG函数了。第i堆石子只能拿\([1,i]\)个石子,先举个例子吧:i=2
先把1~2i的SG求出来:SG[1]=1,SG[2]=2,SG[3]=0,SG[4]=1
好像\(SG[x]=x\%(i+1)\).
数学归纳法证明:
\([0,i]\)必然满足\(SG[x]=x\%(i+1)\).
归纳假设:对于\(x>i\),所有\(y < x\)都满足\(SG[y] = y \% (i+1)\).
\(x = k(i + 1) + b,0 \leq b < i+1 , k > 0\)
则对于任意x能到达的数\(y = (k - 1)(i + 1) + b + c,0 < c \leq i\)
\(SG[y] = (b + c) \% (i + 1)\)取完\(0\)\(i\)所有非\(b\)的数
所以\(SG[x] = b\).
证毕。

所以说,规律自个找,证明没烦恼。

推荐阅读