1. 程式人生 > >【轉】找出遊戲的必勝策略——Nim與Grundy數小記

【轉】找出遊戲的必勝策略——Nim與Grundy數小記

原文地址:http://endless.logdown.com/posts/2014/05/05/find-out-the-winning-strategies-of-the-game-nim-and-grundy-number-notes

原文訪問真心慢,所以轉下,侵權必刪

見 Codeforces 197A Plate Game
(經典博弈,我們選修課老師在上課時提到過此題)
分析:一開始你放一個盤子在桌子中心,然後對手怎麼放,你就關於桌子中心對稱地放,只要一開始你能放一個盤子在中心,那麼最後你肯定能贏。
此乃「以牙還牙,以眼還眼」。

一、基礎知識

一般規則:

  1. i=0為必勝/必敗態(視題目而定);
  2. 某個i-(某個數)為必敗態的話,i為必勝態 / 若i為必敗態,則i+(某個數)為必勝態;
  3. 所有i-(某個數)為必勝態的話,i為必敗態 / 若i為必勝態,則i+(某個數)可能為必敗態,但是若i+(某個數)只有一個後繼,則其必為必敗態

技巧:
如果難以看出必勝/必敗態,不妨從i=0開始畫一棵必勝/必敗態的轉移樹來輔助分析。

一些題目使用記憶化搜尋就可以解決。

>> 有最大取子限制的取石子游戲:POJ 2068 Nim
>> 需要一些技巧性討論的取石子游戲:POJ 1740 A New Stone Game
>> 歐幾里得博弈:POJ 2348 Euclid's Game

 (好題)
>> 弗格森 (Ferguson) 遊戲(大白書 P134)
>> Chomp! 遊戲(大白書 P134)
>> 約束遊戲(大白書 P135)
>> 日曆博弈:POJ 1082 Calendar Game

巴什 (Bash) 博奕
HDU 1846 Brave Game
有 n 個石子,兩個人輪流取 1~m 個石子。最後取光者得勝。
結論:當  時後手勝,否則先手勝。
分析:以牙還牙。當  時,先手取 x 個,那麼後手取 m+1-x 個,最後一定是後手取完;當  時,設 

,一開始先手取 r 個,那麼變成前面  的局面,最後先手取完。

>> 威佐夫 (Wythoff) 博奕與 Beatty 定理
>> 斐波那契 (Fibonacci) 博弈與 Zeckendorf 定理

二、Nim

該遊戲起源於中國,經當年到美洲打工的華人流傳出去。其英文名「NIM」是由廣東話「拈」(取物之意)音譯而來。

1902 年,L.Bouton 腦洞大開,提出瞭如下定理,從而徹底地解決了 Nim 問題:

異或和值為零則後手勝,否則先手勝。

而這個定理兩句話就能解釋明白:

  1. 當異或和值為零時,無論你怎麼取,異或和值一定變為非零,對手以牙還牙,使異或和值變為零,如此迴圈,直至對手取完。故此時先手必敗(處於必敗態)。
  2. 當異或和值非零時,總能在某一堆中選取若干個石頭,使得異或和值為零(可以自己找幾個例子算算),則必勝態總能轉移到必敗態。

一些問題可以轉化為 Nim 問題,常用的思路是兩個兩個分成一組進行思考,注意利用“以牙還牙,以眼還眼”這一技巧。

例題:
UVa 12499 I am Dumb 3
HDU 4315 Climbing the Hill

下面階梯博弈的變形2也可以用分組的思想做。

階梯博弈(Staircase Nim)

博弈在一列階梯上進行,每個階梯上沒有石子或放著若干個石子。兩個人進行階梯博弈,每一步則是將階梯(不是第一層的階梯)上的若干個石子移到(某些指定的)低階的階梯去,最後沒有石子可以移動的人輸。

階梯博弈可以利用遊戲的限制轉化成Nim解決:由於某個階梯上的石子移動到不能移動時所需的步數要麼是奇數,要麼是偶數。對於偶數步,對方用哪些石子走一步你也用哪些石子走一步,從而不影響遊戲結果。所以只對奇數階的石子求Nim就行

例題:HDU 3389 Game

有一些看似與階梯博弈無關的題,揭開它的面紗後,實際上就是階梯博弈:

  1. 博弈在一個N個格子的方塊上進行,每個方塊上至多有一個石子,每次可以選擇一個石子向右移動到最近的空位,不能移動石子的人輸,如下圖所示:

設函式F[i]表示第i個石子移動到不能移動所需要的步數。
然後我們來觀察某一次移動,假設圖中的2跳到了4的後面,我們可以來觀察一下所有石子的F函式有什麼變化:


首先對於1及其之前的石子,它們的F函式顯然不變。
同樣,對於移動後的2之後的石子,它們的F函式也不變。
那麼變化的就是2,3,4這三個石子的F值,變化了多少?每一個減少了1
那麼,如果我們把這個函式F[]看做臺階的階數的話,乃是不是覺得有一點熟悉的感覺了~
沒錯!就是階梯博弈

·2. POJ 1704 Georgia and Bob
也是一行格子和一些石子,每次可以把一個石子往左移動若干步,但是不能越過石子,誰最後不能移動誰輸。
如果將沒有石子的格子看做階梯上的石子,我們會發現移動一個石子實際上是將這個石子左邊的格子移到右邊去,也就是把高度為i的階梯上的石子移到下一個階梯上去(最右邊的空白為第一階),所以還是討論奇偶性~
(這題也可以用兩個兩個一組的思路來思考)

三、Grundy值(SG函式)

我們把 Nim 遊戲加點限制:每次你只能取a1,a2,a3,...an個石頭。
如何轉化成 Nim 問題呢?
原來的 Nim 是 a->a' 的轉化,現在我們改為 SG(a)->SG(a') 的轉化。
見 Wiki 中給出的例子。

Sprague-Grundy 定理(SG 定理):遊戲和的Grundy值等於各遊戲Grundy值的異或和。
很多博弈遊戲都含有遊戲和這一要素,故可用Grundy值很方便的解決。

剪紙博弈
POJ 2311 Cutting Game(程式碼見下)

/*188ms,848KB*/

#define Fpos(a, n, x) (find(a, a + (n), x) - a)
const int mx = 205;

int dp[mx][mx];

int sg(int w, int h)
{
    if (~dp[w][h]) return dp[w][h];
    bool vis[mx] = {0};
    int i;
    Forr(i, 2, w - 1) vis[sg(i, h) ^ sg(w - i, h)] = true; /// 分解出子游戲
    Forr(i, 2, h - 1) vis[sg(w, i) ^ sg(w, h - i)] = true;
    return dp[w][h] = Fpos(vis, mx, false);
}

int main()
{
    mem(dp, -1);
    int w, h;
    while (~SII(w, h)) puts(sg(w, h) ? "WIN" : "LOSE");
    return 0;
}

四、其他

翻硬幣遊戲 (Coin Turning Game)

  1. 一維的翻硬幣遊戲,每次可以翻1個或兩個。通過單獨考慮每個可以翻的硬幣發現,Coin Turning Game的SG值和Nim等價,因此兩個模型等價。需要注意的是,許多翻硬幣遊戲根據題目的要求,一般編號從0開始。
  2. 一維的翻硬幣遊戲,每次可以翻1個或兩個,限定了翻第二枚硬幣的範圍,那麼就和Subtraction Game等價了。
  3. 一維的翻硬幣遊戲,每次可以翻1個、2個或3個,這個遊戲叫做Mock Turtles,有一個神奇的規律,是Odious Number序列。
  4. 高維的翻硬幣遊戲,需要用到Nim積和Tartan定理。 翻硬幣模型的變化更多,很多模型都有一些奇妙的規律,需要打表才能發現。

刪邊遊戲(Green Hackenbush)

  1. 樹的刪邊遊戲:Colon原理證明這種模型和Nim依然是等價的,多個叉的SG值異或就是對應根節點的SG值。
  2. 無向圖刪邊遊戲:利用Fursion定理收縮圈,然後就轉換成樹的刪邊遊戲了,不過這個定理還不會證。