四種博弈論演算法分析

2021-09-18 03:15:09 字數 4211 閱讀 9713

**:

a和b一塊報數,每人每次報最少1個,最多報4個,看誰先報到30。這應該是最古老的關於巴什博奕的遊戲了吧。

其實如果知道原理,這遊戲一點運氣成分都沒有,只和先手後手有關,比如第一次報數,a報k個數,那麼b報5-k個數,那麼b報數之後問題就變為,a和b一塊報數,看誰先報到25了,進而變為20,15,10,5,當到5的時候,不管a怎麼報數,最後乙個數肯定是b報的,可以看出,作為後手的b在個遊戲中是不會輸的。

那麼如果我們要報n個數,每次最少報乙個,最多報m個,我們可以找到這麼乙個整數k和r,使n=k*(m+1)+r,代入上面的例子我們就可以知道,如果r=0,那麼先手必敗;否則,先手必勝。

巴什博奕:只有一堆n個物品,兩個人輪流從中取物,規定每次最少取乙個,最多取m個,最後取光者為勝。

**如下:

#include

using namespace std;

intmain()

例題有:hdu4764 stone:

題目大意:tang和jiang輪流寫數字,tang先寫,每次寫的數x滿足1<=x<=k,jiang每次寫的數y滿足1<=y-x<=k,誰先寫到不小於n的數算輸。

結論:r=(n-1)%(k+1),r=0時jiang勝,否則tang勝。

詳解:bash game:同餘理論

一堆n個物品,兩人輪流取,每次取1至m個,最後取完者勝

比如10個物品,每次只能取1到5個,則先手方必贏

1.面對[1…m]個局面,必勝

2.面對m+1個局面,必輸

3.如果可以使對手面臨必輸局面,那麼是必贏局面

4.如果不能使對手面臨必輸局面,那麼是必輸局面

基礎:1 , 2, …, m是必贏局面, m+1是必輸局面

遞推:m+2,m+3, … ,2m+1是必贏局面,2m+2是必輸局面

…k(m+1)是必輸局面,應該允許k=0,因為0顯然也是必輸局面

在必輸局和必贏局中,贏的一方的策略是: 拿掉部分物品,使對方面臨k(m+1)的局面

例如上例中10個物品,只能拿1到5個,先手方拿4個即可,對手無論拿多少個,你下次總能拿完

從另乙個角度思考這個問題,如果物品數量隨機,那麼先手一方勝利的概率是m/(m+1),後手方勝利的概率是1/(m+1)

ac**:

#include

using namespace std;

intmain()

int r =

(n-1)%

(k+1);

if(r==0)

else

}return0;

}

有兩堆各若干的物品,兩人輪流從其中一堆取至少一件物品,至多不限,或從兩堆中同時取相同件物品,規定最後取完者勝利。

直接說結論了,若兩堆物品的初始值為(x,y),且x記w=(int)[((sqrt(5)+1)/2)*z ];

若w=x,則先手必敗,否則先手必勝。

**如下:

#include

#include

#include

using namespace std;

intmain()

return0;

}

詳解:

nim game:異或理論

m堆n個物品,兩人輪流取,每次取某堆中不少於1個,最後取完者勝

所有物品數目二進位制異或 為0,則先手必輸

所有物品數目二進位制異或不為0,則後手必輸

從另乙個角度思考這個問題,如果物品數量隨機,那麼每個數目的每一位上1或0概率相同,

如果有奇數個堆,那麼1的個數為偶數或者奇數的概率相同,

如果有偶數個堆,那麼1的個數為偶數的概率略大1/(m+1),

也就是說異或結果的每一位為0或1的概率幾乎差不多,而先手必輸要求異或結果每一位都為0,其實輸的概率很小

ac**:

#include

using namespace std;

intmain()

else}if

(temp)

else

}return0;

}

尼姆博弈指的是這樣乙個博弈遊戲:有任意堆物品,每堆物品的個數是任意的,雙方輪流從中取物品,每一次只能從一堆物品中取部分或全部物品,最少取一件,取到最後一件物品的人獲勝。

結論就是:把每堆物品數全部異或起來,如果得到的值為0,那麼先手必敗,否則先手必勝。

**如下:

#include

#include

#include

using namespace std;

intmain()

if(temp==

0) cout<<

"後手必勝"

"先手必勝"

<}return0;

}

詳解:

wythoff game:**分割

兩堆(ak,bk)(ak<=bk)個物品,兩人輪流取,每次從一堆中取k個或者從2堆中同時取k個,最後面對(0,0)局面的輸(設ak<=bk是為了忽略順序的影響)

1.面對(0,0)局面必輸

2.面對(1,1)(2,2)…(n,n)局面必贏

(0,1)(0,2)…(0,n)局面必贏

3.如果可以使對手面臨必輸局面,那麼是必贏局面

4.如果不能使對手面臨必輸局面,那麼是必輸局面

基礎:(0,0)是必輸局面;(0,1)(0 ,2)…(0,n)是必贏局面,

遞推:(1,2)是必輸局面;(1,1)是必贏局面

(1,3)(1 ,4)…(1,n)是必贏局面

(2,2),(2,3)…(2,n)是必贏局面

(3,5)是必輸局面;(3,3)(3,4)是必贏局面

(3,6)(3,7)…(3,n)是必贏局面

(5,5)(5,6)…(5,n)是必贏局面

(4,7)是必輸局面;(4,4)(4,5)(4,6)是必贏局面

(4,8)(4,8)(4,9)…(4,n)是必贏局面

(7,7)(7,8)(7,9)…(7,n)是必贏局面

(6,10)是必輸局面;(6,6)(6,7)(6,8)(6,9)是必贏局面

(6,11)(6,12)(6,13)…(6,n)是必贏局面

(10,10)(10,11)(10,12)…(10,n)是必贏局面

首先發現規律:(必輸局面的規律比較容易找到)

ak是前面必輸局未出現的數中最小者,

bk=ak+k( k=0,1,2,3,…n)

下面介紹必輸局(奇異局)的最重要性質:

1,2,…,n中每乙個自然數,出現且只出現在乙個奇異局中。

推導:1.由於ak總是選擇未出現的數,所以每個數總能出現在奇異局中

且ak不會選擇到重複的數

2.bk=ak+k,所以bk總是比前面所有奇異局出現的數都大,

所以bk不會選擇到重複的數

必贏一方的策略是:始終讓對手面對必輸局(奇異局)

給定任意局勢(a,b),判定(a,b)是否為必輸局的方法是:

k=0,1…n 記**比例是φ=1.618033

ak=[kφ],bk=ak+k=[kφφ]

如k=0,ak=0,bk=0

k=1,ak=1,bk=2

k=2,ak=3,bk=5 k=3,ak=4,bk=7

更好的一種判斷策略是 k = bk-ak ,如ak=kφ時,當前局勢為奇異局

從勝負概率角度,如果堆中數量隨機,先手一方優勢很大

(相應經典題目是poj-1067)

有一堆物品,兩人輪流取物品,先手最少取乙個,至多無上限,但不能把物品取完,之後每次取的物品數不能超過上一次取的物品數的二倍且至少為一件,取走最後一件物品的人獲勝。

結論是:先手勝當且僅當n不是斐波那契數(n為物品總數)

如hdu2516

#include

#include

#include

using namespace std;

const

int n =55;

int f[n]

;void

init()

intmain()

}if(flag)

puts

("second win");

else

puts

("first win");

}return0;

}

博弈論演算法

複習 兩個頂尖聰明的人在玩遊戲,有一堆n個石子,每次每個人能取 1,m 個石子,不能拿的人輸,請問先手與後手誰必敗?結論 通過上面的分析可以得出結論 當n能整除m 1時先手必敗,否則先手必勝。兩個頂尖聰明的人在玩遊戲,有nn堆石子,第ii堆有aiai個,每人每次能從一堆石子中取任意多個石子但不能不取...

博弈論 演算法

博弈論主要研究公式化了的激勵結構間的相互作用,是研究具有鬥爭或競爭性質現象的數學理論和方法。博弈論考慮遊戲中的個體的 行為和實際行為,並研究它們的優化策略。如囚徒困境 鏈結 在演算法競賽 現的博弈論題目通常是icg 公平組合遊戲 的,有如下特徵 1.有兩名選手。2.兩名選手交替操作,每次一步,每步都...

演算法 簡單博弈論

僅有一堆n個物品,兩個人輪流取1 m個,最後取的人勝 不能取的人輸 總體可分幾種情況 int bash game int n,int m 是否先手有必贏策略 將一堆變為多堆 即 有3堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取1個,多者不限,最後取光者得勝。本部分含其他部落格內容...