原題鏈結
給定n堆石子,兩位玩家輪流操作,每次操作可以從任意一堆石子中拿走任意數量的石子(可以拿完,但不能不拿),最後無法進行操作的人視為失敗。
問如果兩人都採用最優策略,先手是否必勝。
輸入格式
第一行包含整數n。
第二行包含n個數字,其中第 i 個數字表示第 i 堆石子的數量。
輸出格式
如果先手方必勝,則輸出「yes」。
否則,輸出「no」。
資料範圍
1≤n≤105,
1≤每堆石子數≤109
輸入樣例:
22 3
輸出樣例:
yes先上一波**
#includeusing namespace std;
int main()
if(res) cout<
1.有兩名選手;
2.兩名選手交替操作,每次一步,每步都是在有限的合法集合中選取一種進行;
3.在任何情況下,合法操作只取決於情況本身,與選手無關;
4.遊戲的敗北條件為:當某位選手需要進行操作時,當前沒有任何可以執行的合法操作,則該選手敗北。
先來介紹nim裡的兩種狀態,先手必敗狀態和先手必勝狀態。
前者是先手走不到任何乙個必敗狀態,即後手無法是必敗狀態,先手必敗。
後者即先手可以走到某個必敗狀態,此時為後手操作,後手必敗。
nim遊戲中有個經典結論:若a1^a2…an==0 則先手必敗。我們可以從簡單的資料入手,比如有兩堆石子的數量分別為2、3。那麼是不是先手必勝呢。我們可以先用結論及**驗證一下。
#includeusing namespace std;
int main()
執行結果如圖
那麼我們現在可以模擬一下具體過程,前提是每個人每一步都是最優策略。先手從石子數為3的堆裡取走乙個石子,此時變為2 2,接下來不論後手做任何操作,先手只需在另一堆石子裡做相同的操作,這樣就再次使得兩堆石子的數目一樣。如此迴圈下去,一定是後手遇到必敗狀態,先手勝利。
接下來進行簡單的證明一下:
首先,當所有的堆的石子數均為0時,異或值也是0,即不能進行任何操作,先手必敗。
然後,如果異或值不為零,即a1^a2…an= k(k為非零常數),先手一定可以某種操作(即從某堆石子中拿走部分石子)讓異或值變為0,此時後手走到了必敗態,先手必勝。(具體為什麼是異或值還有待探索)
假設k的二進位制表示中最高的一位1是第x位, 那麼在a1-an中必存在有乙個數ai的第x位是1;那麼ai^x具體為什麼是異或值為0,可以參考k-nim遊戲;
nim還有很多變形,學習中。
扔一道台階nim的題吧 驚奇隊長和滅霸的決戰 來自臨沂大學新生賽
藍橋杯歷年試題 高僧鬥法 也是如此
最後放一篇寫的很好的高僧鬥法的題解
不當之處,請多指教。
博弈論 Nim遊戲
這種遊戲稱為nim博弈,遊戲過程中面臨的狀態成為局面。n im nimni m博弈不存在平局,只有先手必勝和先手必敗兩種情況。定理nim 博弈先手 必勝,當 且僅當a 1xora2 xor xoran 0nim博弈先手必勝,當且僅當 a 1 texta 2 text cdots text a n n...
博弈論(一) Nim遊戲
重點結論 對於乙個nim遊戲的局面 a1,a2,an 它是p position當且僅當a1 a2 an 0,其中 表示位異或 xor 運算。nim遊戲是博弈論中最經典的模型 之一?它又有著十分簡單的規則和無比優美的結論,由這個遊戲開始了解博弈論恐怕是最合適不過了。nim遊戲是組合遊戲 combina...
博弈論之Nim遊戲
二 nim遊戲的定義 三 過程例項 四 分析 3.bouton s theorem 五 例題 nim遊戲是博弈論中最經典的模型 之一 它又有著十分簡單的規則和無比優美的結論 nim遊戲是組合遊戲 combinatorial games 的一種,準確來說,屬於 impartial combinator...