博弈論 SG和NIM

2022-09-15 15:15:18 字數 4317 閱讀 6561

感覺博弈論acm還蠻經常考,現在我只記得nim結論似乎不太行

博弈論就是要靜下心一口氣先把概念看完才懂啊(所以建議找個時間一口其總結完)

參考了nim遊戲屬於「impartial combinatorial games」(以下簡稱icg):

滿足以下條件的遊戲是icg(可能不太嚴謹):

1、有兩名選手;

2、兩名選手交替對遊戲進行移動(move),每次一步,選手可以在(一般而言)有限的合法移動集合中任選一種進行移動;

3、對於遊戲的任何一種可能的局面,合法的移動集合只取決於這個局面本身,不取決於輪到哪名選手操作、以前的任何操作、骰子的點數或者其它什麼因素;

4、如果輪到某名選手移動,且這個局面的合法的移動集合為空(也就是說此時無法進行移動),則這名選手負。根據這個定義,很多日常的遊戲並非icg。例如象棋就不滿足條件3,因為紅方只能移動紅子,黑方只能移動黑子,合法的移動集合取決於輪到哪名選手操作。

就像我們玩的回合制遊戲有木有

任何乙個icg遊戲都 有不同的局面,而每乙個局面都可以看成乙個頂點,該局面到它的子局面 由有向邊鏈結(模擬一下下棋)

可以抽象為:給定乙個有向無環圖和乙個起始頂點,兩名選手交替的將這頂點沿有向邊進行移動到它的子集,無法移動者判負。

現在定義:先手必勝局面(局面)和先手必敗局面(頂點):

1.無法進行任何移動的局面(也就是terminal position 終局)是特殊的p-position(先手必敗);2.可以移動到p-position的局面是n-position (先手必勝居局面);3.所有移動都導致n-position的局面是p-position 。

然後為了方便表示現在就要引進乙個mex(minimal excludant)運算:表示mex=最小的不屬於這個集合的非負整數

比如:mex=3、mex=0、mex{}=0。

現在再定義 sg函式:對於乙個給定的有向無環圖,關於圖的每個頂點的sprague-garundy(sg)函式如下:sg(x)=mex。

然後這個sg函式有個性質:所有的terminal position所對應的頂點(也就是沒有出邊的頂點|也是先手必敗局面),其sg值為0,因為它的後繼集合是空集(mex{}=0)

然後對於乙個sg(x)=0的頂點x,它的所有後繼y都滿足g(y)!=0。對於乙個sg(x)!=0的頂點,必定存在乙個後繼y滿足sg(y)=0。(即能到達先手必敗局面|當前局面就是先手必勝局面)

但是如果是多堆石子呢,因為任何乙個icg都可以抽象成乙個有向圖遊戲。所以「sg函式」和「遊戲的和」的概念就不是侷限於有向圖遊戲。所以說當我們面對由n個遊戲組合成的乙個遊戲時,只需對於每個遊戲找出求它的每個局面的sg值的方法,就可以把這些sg值全部看成nim的石子堆,然後依照找nim的必勝策略的方法來找這個遊戲的必勝策略了!

發現還是只用nim的結論

所以我們可以定義有向圖遊戲的和(sum of graph games):設g1、g2、……、gn是n個有向圖遊戲,定義遊戲g是g1、g2、……、gn的和(sum),遊戲g的移動規則是:任選乙個子遊戲gi並移動上面的棋子。sprague-grundy theorem就是:sg(g)=sg(g1)^sg(g2)^…^sg(gn)。也就是說,遊戲的和的sg函式值是它的所有子遊戲的sg函式值的異或。

:每乙個子遊戲最終都只有乙個sg值 如sg(n)而這個sg值要從sg(0),開始逆推,所以不要誤以為是每個節點i的sg(i)值取xor

如果是可選步數為1~m的連續整數,直接取模即可,sg(x) = x % (m+1);

如果可選步數為任意步,sg(x) = x;

如果可選步數為一系列不連續的數,用模板計算(dp|dfs)。

例:有t堆石子,每次可以從第1堆石子裡取1顆、2顆或3顆,可以從第2堆石子裡取奇數顆,可以從第3堆及以後石子裡取任意顆……假設第一堆有n個石子,第二堆有m個,其餘的有a[1]~a[t-2]個石子,我們可以把它看作3個子遊戲,第1個子遊戲只有一堆石子,每次可以取1、2、3顆,可以得出sg1[n]值是n%4。第2個子遊戲也是只有一堆石子,每次可以取奇數顆,經過簡單的畫圖可以知道這個遊戲的sg2[m]值是x%2。第3個遊戲有t-2堆石子,就是乙個nim遊戲即sg3=sg[a[i]]^sg[a[2]]...。對於原遊戲的每個局面,把三個子遊戲的sg值異或一下就得到了整個遊戲的sg值,sg=sg1[n]^sg2[m]^sg3然後就可以根據這個ifsg ==0 ==>必敗,否則必勝

下面貼一下可以取不連續的數的模板:

這題似乎交不了??!!還是貼一下**吧

題目大意:若輸入n=0代表結束,否則輸入n(n<10),s(<2^13),n代表有n*2個人,s代表一共有s個石子 ,然後有n*2個數a1,a2....代表第i個人最多能拿的石子數,你擁有奇數的隊員(1,3,5...),每次按順序來取,不斷迴圈,最後誰的組員把石堆拿走最後乙個石子誰輸(sg[1]=0,sg[0]=1),若這組資料你能能贏輸出1,否則輸出0。

因為只有一堆石子,直接判斷正負狀態就行了,用記憶化搜尋|dp都可以

#include#include

#include

#include

#include

using

namespace

std;

const

int n=20,m=(2

<<13)+1431

;int n,s,x,sg[n*2][m],a[2*n];//

這裡的sg實際上是表示輸贏0|1

int dfs(int x,int

sum)

if(sum<=0

)

if(sg[x][sum]!=-1

)

return

sg[x][sum];

sg[x][sum]=0; //

預先假定現在是先手必輸局面記

for(int i=1;i<=a[x];i++)

}return

sg[x][sum];

}int

main()

printf(

"%d\n

",dfs(0

,s));

}return0;

}

就是個nim模板

#include#include

#include

#include

#include

using

namespace

std;

const

int n=10006

;int n,ans=0

,sg[n],x,t,use[n];

void get_sg(int n)//

得到每乙個點的sg值 }}

}int

main()

if(ans>0) //

xor的結果不一定是1除非是上題那種直接判斷當前sg是p|n局面才是0|1

printf("

yes\n");

else

printf(

"no\n");

}return0;

}

如果上上題那種直接判斷當前sg是p|n局面最後發現結果並不對,意思是sg值和輸贏0|1各自的xor並不同也就是說直接判斷輸贏只能用於乙個遊戲中

n個遊戲就應該求出每乙個遊戲的sg值再xor判斷

博弈論 Nim博弈 反Nim博弈 SG函式

nim遊戲 hdu1846 若各堆石子異或和為不為零,則先手勝 後手當且僅當異或和為零時取勝 此題問要想先手取勝第一步的取法,考慮到上述引理,只需遍歷一遍石子找到異或和的最高位匹配的個數。int a 105 int main return0 view code hdu 1848 在上題的基礎上取法只...

博弈論 Nim遊戲與SG函式

普通nim遊戲 有若干堆石子,兩人輪流從中取石子,取走最後乙個石子的人為勝利者 我們判斷先手必勝還是先手必敗就要判斷先手面對的局面是必勝態還是必敗態 並且普通nim遊戲滿足以下性質 1.無法移動的狀態是必敗態 2.可以移動到必敗態的局面一定是非必敗態 3.在必敗態做所有操作的結果都是非必敗態 這些性...

博弈論 Nim博弈

1.nim博弈的起源很早,至於歷史我們就不再說了,直接說它的使用場景。1 依舊是兩個人博弈,但是物品時n堆,每一堆有ai個。2 每個人可以挑選一堆取走若干個,但是不能不取。3 最先取完所有物品的人獲勝。4 結論 所以堆的物品的數量異或起來是0,先手必敗。2.乙個nim博弈的例項 nim博弈。乍一看這...