有n堆石子,每次可以從第1堆石子裡取1顆、2顆或3顆,可以從第2堆石子裡取奇數顆,可以從第3堆及以後石子裡取任意顆……這時看上去問題複雜了很多,但相信你如果掌握了本節的內容,類似的千變萬化的問題都是不成問題的。
現在我們來研究乙個看上去似乎更為一般的遊戲:給定乙個有向無環圖和乙個起始頂點上的一枚棋子,兩名選手交替的將這枚棋子沿有向邊進行移動,無法移動者判負。事實上,這個遊戲可以認為是所有impartial combinatorial games的抽象模型。也就是說,任何乙個icg都可以通過把每個局面看成乙個頂點,對每個局面和它的子局面連一條有向邊來抽象成這個「有向圖遊戲」。下面我們就在有向無環圖的頂點上定義sprague-garundy函式。
首先定義mex(minimal excludant)運算,這是施加於乙個集合的運算,表示最小的不屬於這個集合的非負整數。例如mex=3、mex=0、mex{}=0。
對於乙個給定的有向無環圖,定義關於圖的每個頂點的sprague-garundy函式g如下:g(x)=mex。
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值,就可以對每種局面找到必勝策略了。但sg函式的用途遠沒有這樣簡單。如果將有向圖遊戲變複雜一點,比如說,有向圖上並不是只有一枚棋子,而是有n枚棋子,每次可以任選一顆進行移動,這時,怎樣找到必勝策略呢?
讓我們再來考慮一下頂點的sg值的意義。當g(x)=k時,表明對於任意乙個0<=i
對於n個棋子,設它們對應的頂點的sg值分別為(a1,a2,...,an),再設局面(a1,a2,...,an)時的nim遊戲的一種必勝策略是把ai變成k,那麼原遊戲的一種必勝策略就是把第i枚棋子移動到乙個sg值為k的頂點。這聽上去有點過於神奇——怎麼繞了一圈又回到nim遊戲上了。
其實我們還是只要證明這種多棋子的有向圖遊戲的局面是p-position當且僅當所有棋子所在的位置的sg函式的異或為0。這個證明與上節的bouton's theorem幾乎是完全相同的,只需要適當的改幾個名詞就行了。
剛才,我為了使問題看上去更容易一些,認為n枚棋子是在乙個有向圖上移動。但如果不是在乙個有向圖上,而是每個棋子在乙個有向圖上,每次可以任選乙個棋子(也就是任選乙個有向圖)進行移動,這樣也不會給結論帶來任何變化。
所以我們可以定義有向圖遊戲的和(sum of graph games):設g1、g2、……、gn是n個有向圖遊戲,定義遊戲g是g1、g2、……、gn的和(sum),遊戲g的移動規則是:任選乙個子遊戲gi並移動上面的棋子。sprague-grundy theorem就是:g(g)=g(g1)^g(g2)^...^g(gn)。也就是說,遊戲的和的sg函式值是它的所有子遊戲的sg函式值的異或。
再考慮在本文一開頭的一句話:任何乙個icg都可以抽象成乙個有向圖遊戲。所以「sg函式」和「遊戲的和」的概念就不是侷限於有向圖遊戲。我們給每個icg的每個position定義sg值,也可以定義n個icg的和。所以說當我們面對由n個遊戲組合成的乙個遊戲時,只需對於每個遊戲找出求它的每個局面的sg值的方法,就可以把這些sg值全部看成nim的石子堆,然後依照找nim的必勝策略的方法來找這個遊戲的必勝策略了!
回到本文開頭的問題。有n堆石子,每次可以從第1堆石子裡取1顆、2顆或3顆,可以從第2堆石子裡取奇數顆,可以從第3堆及以後石子裡取任意顆……我們可以把它看作3個子遊戲,第1個子遊戲只有一堆石子,每次可以取1、2、3顆,很容易看出x顆石子的局面的sg值是x%4。第2個子遊戲也是只有一堆石子,每次可以取奇數顆,經過簡單的畫圖可以知道這個遊戲有x顆石子時的sg值是x%2。第3個遊戲有n-2堆石子,就是乙個nim遊戲。對於原遊戲的每個局面,把三個子遊戲的sg值異或一下就得到了整個遊戲的sg值,然後就可以根據這個sg值判斷是否有必勝策略以及做出決策了。其實看作3個子遊戲還是保守了些,乾脆看作n個子遊戲,其中第1、2個子遊戲如上所述,第3個及以後的子遊戲都是「1堆石子,每次取幾顆都可以」,稱為「任取石子遊戲」,這個超簡單的遊戲有x顆石子的sg值顯然就是x。其實,n堆石子的nim遊戲本身不就是n個「任取石子遊戲」的和嗎?
所以,複雜的遊戲試圖分成若干個子遊戲,對於每個比原遊戲簡化很多的子遊戲找出它的sg函式,然後全部異或起來就得到了原遊戲的sg函式,就可以解決原遊戲了。
首先定義mex(minimal excludant)運算,這是施加於乙個集合的運算,表示最小的不屬於這個集合的
非負整數
。例如mex=3、mex=0、mex{}=0。
對於乙個給定的有向無環圖,定義關於圖的每個頂點的
sprague-grundy
函式g如下:g(x)=mex,
這裡的g(x)即sg[x]
例如:取石子問題,
有1堆n個的石子
,每次只能取個石子,先取完石子者勝利,那麼各個數的sg值為多少?
sg[0]=0
,f=, x表示石子
x=1時,可以取走1-f個石子,剩餘個,mex=,故sg[1]=1; 最小的數
x=2時,可以取走2-f個石子,剩餘個,mex=,故sg[2]=0;
x=3時,可以取走3-f個石子,剩餘個,mex=,故sg[3]=1;
x=4時,可以取走4-f個石子,剩餘個,mex=,故sg[4]=2;
x=5時,可以取走5-f個石子,剩餘個,mex=,故sg[5]=3;
以此類推.....
x 0 1 2 3 4 5 6 7 8....
sg[x] 0 1 0 1 2 3 2 0 1....
計算從1-n範圍內的sg值。
f(儲存可以走的步數,f[0]表示可以有多少種走法)
f需要從小到大排序
1.可選步數為1~m的連續整數,直接取模即可,sg(x) = x % (m+1);
2.可選步數為任意步,sg(x)
= x;
3.可選步數為一系列不連續的數,用getsg()計算
//f:可以取走的石子個數
//sg:0~n的sg函式值
//hash:mex{}
int f[n],sg[n],hash[n];
void getsg(int n)
中未出現的最小的非負整數
} }
}
hdu 1848
題意:取石子問題,
一共有3堆石子
,每次只能取斐波那契數個石子,先取完石子者勝利,問先手勝還是後手勝
可選步數為一系列不連續的數,用getsg(計算)
最終結果是所有sg值異或的結果
博弈論 (SG函式)
首先定義mex minimal excludant 運算,這是施加於乙個集合的運算,表示最小的不屬於這個集合的非負整數。例如mex 3 mex 0 mex 0。對於乙個給定的有向無環圖,定義關於圖的每個頂點的sprague grundy函式g如下 g x mex,這裡的g x 即sg x 例如 取石...
博弈論 SG函式
學習博弈論不得不提一哈sg函式 關於sg函式的一些概念就不多說了 說下我自己的理解sg函式記錄為0的是p狀態 不為0記錄的是n狀態 相當於有個週期再迴圈 p n狀態輪番出現 sg模板 include include include define maxn 1000 using namespace s...
博弈論 sg函式
定義 給定乙個有向無環圖和乙個起始頂點上的一枚棋子,兩名選手交替的將這枚棋子沿有向邊進行移動,無法移 動者判負。事實上,這個遊戲可以認為是所有公平組合遊戲的抽象模型。在有向圖遊戲中,對於每個節點x,設從x出發共有k條有向邊,分別到達節點y1,y2,yk,定義sg x 為x的後繼節點y1,y2,yk的...