博弈論入門之nim游戲


更好的閱讀體驗點這里

nim游戲

nim游戲
有兩個頂尖聰明的人在玩游戲,游戲規則是這樣的:
\(n\)堆石子,兩個人可以從任意一堆石子中拿任意多個石子(不能不拿),沒法拿的人失敗。問誰會勝利

nim游戲是巴什博奕的升級版(不懂巴什博奕的可以看這里)

它不再是簡單的一個狀態,因此分析起來也棘手許多

如果說巴什博奕僅僅博弈論的一個引子的話,

nim游戲就差不多算是真正的入門了

博弈分析

面對新的博弈問題,我們按照套路,從簡單的情況入手

當只有一堆石子的時候,先手可以全部拿走。先手必勝

當有兩堆石子且石子個數相同的時候,先手不論拿多少,后手都可以從另一堆中拿同樣多的石子,先手必敗,否則先手必勝

當有三堆的時候呢?

當有\(n\)堆的時候呢?

這樣玩下去確實是很繁瑣,不過前輩們總結出了一條非常厲害的規律!

定理解析

定理

對於nim游戲,前輩們發現了一條重要的規律!

\(n\)堆石子的數量異或和等於\(0\)時,先手必勝,否則先手必敗

證明

\(\oplus\)表示異或運算

nim游戲的必敗態我們是知道的,就是當前\(n\)堆石子的數量都為零

\(a[i]\)表示第\(i\)堆石子的數量,那么當前局面就是

$0 \oplus 0 \oplus 0 \oplus \dots \oplus 0 = 0 $

  • 對於先手來說,如果當前局面是

\(a_1 \oplus a_2 \oplus a_3 \oplus \dots \oplus a_n = k\)

那么一定存在某個\(a_i\),它的二進制表示在最高位\(k\)上一定是\(1\)

我們將\(a_i \oplus k\),這樣就變成了

\(a_1 \oplus a_2 \oplus a_3 \oplus \dots \oplus a_n \oplus k = 0\)

此時先手必勝

  • 對於先手來說,如果當前局面是

\(a_1 \oplus a_2 \oplus a_3 \oplus \dots \oplus a_n = 0\)

那么我們不可能將某一個\(a_i\)異或一個數字后使得

\(a_1 \oplus a_2 \oplus a_3 \oplus \dots \oplus a_n = 0\)

此時先手必敗

代碼

#include<cstdio>
using namespace std;
int a[10001]; 
int main()
{
    int Test;
    scanf("%d",&Test);
    while(Test--)
    {
        int ans=0,N;
        scanf("%d",&N);
        for(int i=1;i<=N;i++) scanf("%d",&a[i]);
        for(int i=1;i<=N;i++) ans=ans^a[i];
        ans==0?printf("No\n"):printf("Yes\n");
    }
    return 0;
}

題目

臨時還沒有做太多題目,以后做多了慢慢補吧

題解

估計沒幾個人能一眼秒吧233

題解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM