根據遊戲規則無法再進行行動者為負。
就是將各個子遊戲的sg值進行異或,不為零則初始為n態(先手必勝)。比如抓石子遊戲,sg[i]=i。
取走最後乙個石子者為負。(終止態為n態)
先手必勝當且僅當:
1.所有堆的石子數都為1,且遊戲的sg值為0(此時退化為簡單的奇偶處理)
2.存在石子數大於1的堆,且遊戲的sg值不為0
入門例題:lightoj 1253 misere nim
#include
#include
using namespace std;
int a[
105]
;int
main()
for(
int i=
0;i) ans^
=a[i];if
((ans&&flag)||(
!flag&&
!ans)
)printf
("case %d: alice\n"
,tt)
;else
printf
("case %d: bob\n"
,tt);}
return0;
}
關於sg函式,大佬的文章講的非常清楚
關於sg函式的入門題目:
lightoj 1296 again stone game
還是取石子遊戲,只是加上乙個限制,每次最多不能超過該堆石子總數的一半(向下取整)
所以顯然,石子數為1時是乙個p態(無法取了)。數量=2時只能取乙個,他的後繼狀態就是數量=1,所以sg[2]=mex(sg[1])=1。同理,sg[3]=mex(sg[2])=0。
因為資料量很大(1e9)沒法打表,所以找下規律。
多推幾個就會發現,數量i是偶數時,sg[i]=i/2;數量i是奇數時,sg[i]=sg[i/2]。
**:
#include
#include
using namespace std;
intsg
(int x)
intmain()
if(ans)
printf
("case %d: alice\n"
,tt)
;else
printf
("case %d: bob\n"
,tt);}
return0;
}
lightoj 1315 game of hyper knights
可以說是sg打表的模板題了。
左上角的點肯定是p態,從左上角開始打表,每個點的sg值就是mex。
因為計算當前點時會用到後繼點的sg,所以打表時需要斜著打。
**:
#include
#include
#include
#define n 505
using namespace std;
int sg[n]
[n];
int hash[n]
;void
getsg()
}}}int
main()
if(ans)
printf
("case %d: alice\n"
,tt)
;else
printf
("case %d: bob\n"
,tt);}
return0;
}
lightoj 1199 partitioning game
有n堆石子,每次選一堆將其分成數量不等的兩堆。不能分的人輸。
顯然,1和2是p態,sg=0。
3可以分成1和2,然後對手無法分割,是n態;4只能分成1和3,然後對手把3分成1和2,自己無法分割,所以4是p態。這兩個比較好推,因為3和4都只有乙個後繼狀態。
對於5,可以分成1+4和2+3,根據sg值的定義,
應該是求mex。
對於1+4的sg值的求法,應該是sg[1] ^ sg[4]。因為將1+4這個狀態單拿出來看成乙個新遊戲,這個子遊戲的sg值就是sg[1] ^ sg[4],而sg[1]和sg[4]都已經求出,所以可以這樣通過前面的sg值一步步推出全部的sg值。
所以sg[i]=mex (1<=j<(i+1)/2)
**:
#include
#include
#include
#define n 10005
using namespace std;
int sg[n]
,hash[n]
;void
getsg()
}}intmain()
if(ans)
printf
("case %d: alice\n"
,tt)
;else
printf
("case %d: bob\n"
,tt);}
return0;
}
博弈論入門總結
1 巴什博弈 hdu 1846 題目大意 有一堆石子一共有n個,兩人輪流進行取石子,每走一步可以取走1 m個石子,最先取光石子的一方為勝 如果遊戲的雙方使用的都是最優策略,請輸出哪個人能贏。input 輸入資料首先包含乙個正整數c c 100 表示有c組測試資料。每組測試資料佔一行,包含兩個整數n和...
博弈論入門
博弈論 是二人或多人在平等的對局中各自利用對方的策略變換自己的對抗策略,達到取勝目標的理論。博弈論是研究互動決策的理論。博弈可以分析自己與對手的利弊關係,從而確立自己在博弈中的優勢,因此有不少博弈理論,可以幫助對弈者分析局勢,從而採取相應策略,最終達到取勝的目的。一.bash博弈 問題 只有一堆n個...
博弈論入門
參考 三個簡單的博弈論問題 博弈 1066 bash遊戲 原題傳送 有一堆石子共有n個。a b兩個人輪流拿,a先拿。每次最少拿1顆,最多拿k顆,拿到最後1顆石子的人獲勝。假設a b都非常聰明,拿石子的過程中不會出現失誤。給出n和k,問最後誰能贏得比賽。例如n 3,k 2。無論a如何拿,b都可以拿到最...