恩,本文會簡要介紹一下nim取石子遊戲與sg函式,並附上一些有趣的例題。
首先,讓我們來看一看最簡單的取石子遊戲。
遊戲1規則:有x個石子,兩人輪流取,最多取y個,不能不取,沒得取的人輸,兩個人都按照最優策略進行遊戲,問先手必勝的充要條件。
答案:x mod (y+1) != 0
恩,剛才那個遊戲很簡單,下面讓我們來看乙個稍微難一點的。
遊戲2規則:有x個石子,兩人輪流取,最多取y個,最少取z個,且z<=y,沒得取的人輸,兩個人都按照最優策略進行遊戲,問先手必勝的充要條件。
恩,如果大家都沒想出來的話。那我就不公布答案了,我其實想借這個問題引入必勝態和必敗態的概念。
我們定義必勝態為先手一定能贏的局面,必敗態為先手一定不能贏的局面。然後,對於乙個局面,不是必勝態就是必敗態(因為沒有平局)。
那麼顯然,對於乙個局面a,設b為所以可以轉移到局面a的局面的集合。
那麼a為必勝態當且僅當存在b屬於b,滿足b是必敗態;
那麼a為必敗態當且僅當對於所有b屬於b,滿足b是必勝態。
這個東東的證明是很簡單地,如果存在b是必敗態,乙個聰明的人就會讓對方處於必敗態,然後自己取勝,如果所有b都是必勝態,那麼再怎麼聰明的人也只能讓對方處於必勝態,然後自己心甘情願的輸掉比賽。
有點無聊,那我們就來點資料吧:對於遊戲2,x=9,y=2,z=4,寫出0-9的先手必勝態表,必勝態用w表示,必敗態用l表示。
0123456789
lwwwwllwww
如果用熟悉的的動態規劃來做,那麼動規方程就是f[i]=or(f[i]=true表示i為必勝態)。
然後問題再變難一點。
遊戲3規則:有y個石子,兩人輪流取,可以取x個,x屬於數集x,沒得取的人輸,兩個人都按照最優策略進行遊戲,問哪些是必勝態。
恩,這個問題留給大家思考。
遊戲4規則:有n堆石子,每堆有xi個石子,兩人輪流取,可以在一堆中取任意的石子,但不能不取,也不能跨堆取,沒得取的人輸,兩個人都按照最優策略進行遊戲,問哪些是必勝態。
比如有這樣3堆:7 11 13。大家可以先討論一下。
下面我們引入用異或解nim取石子問題。讓我們來證明一些東西:
對於a1,a2,...,an,設sg=a1 xor a2 xor ... xor an。
引理1若sg!=0,那麼必然存在0<=k
引理2若sg=0,那麼不存在0<=k
下面,我們把異或和nim聯絡到一起。
對於乙個局面(a1,a2,...,an),設sg=a1 xor a2 xor ... xor an。
則它為必敗態當且僅當sg=0。
首先,我們知道(0,0,...,0)是必敗態,這時sg=0,所以命題在這總情況下成立。
然後對於乙個局面(a1,a2,...,an),若a1 xor a2 xor ... xor an != 0,由引理1可知,存在0<=k
例題1(poj1704[georgia and bob])
題目描述:
兩個人玩遊戲,在標有1,2,3,4,5...的格仔上有一些棋子,規則是選一枚棋子移動,要求不能跨越棋子移動,必需向左移動(可以移動任意格),不能移動的就輸掉比賽。
下面是乙個棋局的例子:
+--+--+--+--+--+--+--+--+--+
|1x|2 |3x|4 |5 |6x|7x|8 |9 |(旁邊標有x的表示在這裡有棋子)
+--+--+--+--+--+--+--+--+--+
給出棋子的初始位置,若先手勝,輸出"georgia will win",否則輸出"bob will win"(不含引號)。
輸入格式:
多組資料。
對於每組資料,第一行是有乙個t,表示有t組資料。
對於每組資料,第一行有乙個n,表示有n枚棋子。
接下來的一行有n個數,分別為每個棋子的位置。
輸出格式:
對每組資料,輸出一行,如題目描述那樣。
樣例輸入:23
1 2 3
81 5 6 7 9 12 14 17
樣例輸出:
bob will win
georgia will win
資料範圍:
不管了,大家想演算法就行了,不管時空複雜度。
題解:我們從右到左,將每2個棋子看成一對來處理。
如果對方移動某對棋子中的左邊棋子x步,那麼我方就移動右邊棋子x步。
如果對方一定某對棋子中的右邊棋子,那麼就可以看作nim遊戲了。
剛剛我們研究了一下最最樸素的nim遊戲,下面我們要更深入的理解sg函式。首先sg函式的定義sg(x)=mex(),其中mex(x)=min。
先解釋一下mex函式,mex函式的引數是乙個由一些自然數組成的數集,返回最小的沒有出現在這個數集中的自然數,特別的,如果mex作用在空集上,返回的是0。
再解釋一下sg函式,sg函式的引數是乙個局面,返回乙個自然數,就是這個局面的sg值。
首先,對於乙個局面x,
如果sg(x)!=0,x可以轉移到sg值為0到sg(x)-1的局面,模擬nim遊戲,就是當前有sg(x)顆石子,可以取它,剩下0到sg(x)-1顆石子,與此同時x可能轉移到某些sg值大於sg(x)的局面y,但是此時對手總可以再將局面y轉移回sg值為sg(x)的局面,直至當前選手必選將局面轉移到sg值為0到sg(x)-1的局面;
如果sg(x)=0,那麼要不是x不能轉變到任何狀態(必敗態),就是x只能轉到sg值非0的狀態,模擬nim遊戲,就是取到0顆後就不能再取了,因為如果能夠轉到y,那麼sg(y)!=0,對方又可以讓y轉到sg值為0的狀態,直至沒有前驅。
乙個局面x,設y=sg(x),那麼它就相當於有y顆石子的堆。
對於局面(x1,x2,...,xn),它有子局面x1,x2,...,xn,那麼就相當於有n堆石子,分別有sg(x1),sg(x2),...,sg(xn)顆石子。
所以局面(x1,x2,...,xn)為必敗態當且僅當sg(x1) xor sg(x2) xor ... xor sg(xn)=0。
並且對於局面(x1,x2,...,xn)不給證明的給出下面的結論,sg((x1,x2,...,xn))=sg(x1) xor sg(x2) xor ... xor sg(xn)。
證明:
對於a1,a2,...,an,設sg=a1 xor a2 xor ... xor an。
引理3對任意0<=sg'
例題2(poj2960[s-nim])
題目描述:
兩個人玩遊戲,規則是有n堆石子,分別有a1,a2,...,an顆石頭,每次從一堆石子中取一些石子,但是可取的石子數是規定了的,必須是中的乙個,誰無法操作就輸。
輸入格式:
多組資料。
對於每組資料,第一行是有乙個k,接下來有k個數,分別為s1,s2,...,sk。
第二行有乙個數m,表示會給出m個局面。
接下來的m行,先是乙個n,然後有n個數,分別為a1,a2,...,an。
若k=0,表示資料結束。
輸出格式:
對每組資料,輸出一行m個字元組成的字串,分別表示該組資料中的n個局面是必勝態還是必敗態,必勝態用w表示,必敗態用l表示。
樣例輸入:
2 2 5
32 5 12
3 2 4 7
4 2 3 7 12
5 1 2 3 4 5
32 5 12
3 2 4 7
4 2 3 7 12
0樣例輸出:
lwwwwl
資料範圍:
不管了,大家想演算法就行了,不管時空複雜度。
題解:sg(x)=mex=mex。
例題4(poj2425[a chess game])題目描述:
兩個人玩遊戲,規則是給定乙個有向無環圖,在一些節點上放了棋子,兩人輪流移動棋子,每次只能選一顆棋子沿邊走一步(乙個地方可以放任意多的棋子),最後如果不能走了就輸。
輸入格式:
多組資料。
每組資料的第一行是n,表示圖有n各節點,依次標號為0,1,...,n-1。
接下來的n行,分別表述0,1,..,n-1的出邊。
這n行,第乙個數x表示出度,接下來的x個數分別為該節點的後繼。
接下來有一些詢問。
每個詢問以乙個數m開頭,若m=0則表示詢問結束,否則有m個數,分別為m個棋子所在的節點編號。
輸出格式:
對每個詢問,如果是先手必勝輸出"win",否者輸出"lose"(不含引號)。
樣例輸入:
42 1 2
01 3
01 0
2 0 204
1 11 200
2 0 1
2 1 1
3 0 1 3
0樣例輸出:
winwin
winlose
win資料範圍:
不管了,大家想演算法就行了,不管時空複雜度。
題解:對於乙個棋子sg(x)=max。對於m個棋子,sg((x1,x2,...,xm))=sg(x1) xor sg(x2) xor ... xor sg(xm)。
其它題目推薦poj2975[nim],poj2234[matches game],poj1067[取石子遊戲],usaco[holiday 2010 bonus competition/glod]rocks。
博弈論 Nim遊戲與SG函式
普通nim遊戲 有若干堆石子,兩人輪流從中取石子,取走最後乙個石子的人為勝利者 我們判斷先手必勝還是先手必敗就要判斷先手面對的局面是必勝態還是必敗態 並且普通nim遊戲滿足以下性質 1.無法移動的狀態是必敗態 2.可以移動到必敗態的局面一定是非必敗態 3.在必敗態做所有操作的結果都是非必敗態 這些性...
博弈論之Nim博弈與sg函式(一)
nim博弈 nim遊戲是博弈論中最經典的模型 之一?它又有著十分簡單的規則和無比優美的結論,由這個遊戲開始了解博弈論恐怕是最合適不過了。nim遊戲是組合遊戲 combinatorial games 的一種,準確來說,屬於 impartial combinatorial games 以下簡稱icg 滿...
博弈論 Nim博弈 反Nim博弈 SG函式
nim遊戲 hdu1846 若各堆石子異或和為不為零,則先手勝 後手當且僅當異或和為零時取勝 此題問要想先手取勝第一步的取法,考慮到上述引理,只需遍歷一遍石子找到異或和的最高位匹配的個數。int a 105 int main return0 view code hdu 1848 在上題的基礎上取法只...