1.巴什博弈
問題描述一般為,有一堆物品,有n個,a、b輪流從中取物,最少取乙個,最多取m個,規定取走最後一堆的人獲勝。
對於博弈問題,首先需要分析的是它的必敗情況。由題目可知,假設當前的人a面對的物品堆已空,即為0時,就輸了,所以最基本的必敗為0。那麼根據取物品的取值為1~m,可以知道,在上一步b取物的時候,那一堆只剩下1~m個了,根據兩人都採取最優策略的原則,a在可能的情況下絕對不會讓b遇到1~m這種情況,除非當前a遇到的那一堆是1+m個的,而自己必須至少取乙個,才會導致這種局面。換言之,如果初始的時候,n%(m+1)==0,那麼每當先手取走k,後手都可以通過取m+1-k使得先手再次面臨n%(m+1)==0的必敗局面。因此只要n%(m+1)==0 則先手必敗,否則 當n%(m+1)==k 【通過取餘可知 k<=m】時,先手都可以通過取走k個使得後手面臨n%(m+1)==0
的必敗局面。
乙個類似的變相問題:兩個人輪流報數,每次至少報乙個,至多報m個,報到第n個者勝。
推薦:hdu 1846,2147,2149,2188。
p/n圖分析: p表示必敗點 遇到該點局勢的人必敗 n表示必勝點 遇到該點局勢的人必勝 注:前提是兩者都不失誤
對於p點來說,他的每乙個下乙個承接狀態都是必勝點n。對於n點來書,他的每乙個下乙個承接狀態中至少有乙個p。
那麼圖的終結點,也就是結束狀態,為p的,因為無論誰面對這個狀態都是輸。然後逆向推導即可。注意從邊界開始推。
2.斐波那契博弈
一堆個數為n的石子,輪流取石。
規定:1.先手不能一次取完
2.如果上乙個人取了x,那麼現在這個人可以取1·~2*x
介紹乙個定理:齊肯多夫定理:任何正整數都可以被分解為任意個不連續(注意不連續很重要)的斐波那契數之和。
對於斐波那契來說,f[i]=f[i-1]+f[i-2],那麼如果是兩個不連續的斐波那契的話,也就是最接近的情況為f[i]和f[i-2],而f[i]=f[i-1]+f[i-2],因為f[i-1]>f[i-2],所以f[i]>2*f[i-2];這裡出現了兩倍,於是聯想到了斐波那契博弈的要求,取的數量為1~2*x。(解釋亂七八糟:暫時自己也想不通,先記一下結論)
所以將一開始的整數分解為若干個不連續的斐波那契數列和(分成多個堆),由於不連續斐波那契的f[i]>2*f[i-2]關係,因此如果一開始的數是乙個斐波那契數的話,那麼a必須是在後手才能取走最後乙個。而如果他不是乙個斐波那契數的話,那麼a可以先手取走k使得對手面臨乙個斐波那契數。
因此結論:如果一開始是斐波那契,則後手贏,如果一開始不是斐波那契,則先手贏。即面對斐波那契數的人必輸。
3.威佐夫博弈 證明需要用到betty定理
問題描述:有兩堆物品,各為若干個,兩個輪流任意從其中一堆或者同時從兩堆中取相同的任意個(可以至少把一堆取完)。每次至少取乙個,取光者勝。
分析:用(ai,bi)表示局勢(兩堆各自的數量),當a面對(0,0)時,a必輸,稱此為奇異局勢。列舉出前幾個奇異局勢,為(0,0),(1,2)
(3,5),(4,7),(5,9)
規律為 ai為之前的局勢中沒有出現的第乙個數,bi=ai+i。
奇異局勢有的性質:
1.任何自然數僅僅包含在乙個奇異局勢中
ak>ak-1 由於 bk=ak+k>ak-1+k-1=bk-1>ak-1
2.任意操作都可以將奇異局勢變為非奇異局勢
1)如果當前局勢為(x,y) 如果選擇改變其中乙個分量,那麼由於另外乙個分量不變,所以不可能變為另外乙個奇異局勢。
2)如果x,y同時改變,由於其差值不變,因此也不會變為另乙個奇異局勢。
3.用適當的方法可以將非奇異局勢變為奇異局勢
結論:對於乙個奇異局勢(ak,bk) 我們可以發現 ak=k*(sqrt(5)+1)/2 【**分割比】 而bk=ak+k
因此 如果(bk-ak)* (sqrt(5)+1)/2 =ak,那麼就是奇異局勢(必敗局勢)。
#include
#include
using namespace std;
int main()
int c=b-a;
if(a==(floor((sqrt(5.0)+1)/2*c)))
else
} return 0;
}4.妮姆博弈
問題描述:n堆物品,兩個人輪流從某一堆中取任意多的物品。
三堆的妮姆博弈的基本奇異局勢(0,0,0) (0,n,n) 對於第二個來說,如果當前者在某一堆中取了x,另乙個人可以在另一堆中取x使得第乙個人再次面對 (0,n,n) 。所以可以猜測,妮姆博弈的奇異局勢的特點為,每堆個數抑或起來結果為0。如果不為0的話,假設前n-1堆抑或的結果為x,只要將最後一堆變為x就可以了。
結論:抑或結果為0是奇異局勢,面對其者必敗。
妮姆博弈-階梯博弈
藍橋杯 高僧鬥法
時間限制:1.0s 記憶體限制:256.0mb
問題描述
古時喪葬活動中經常請高僧做法事。儀式結束後,有時會有「高僧鬥法」的趣味節目,以舒緩壓抑的氣氛。
節目大略步驟為:先用糧食(一般是稻公尺)在地上「畫」出若干級台階(表示n級浮屠)。又有若干小和尚隨機地「站」在某個台階上。最高一級台階必須站人,其它任意。(如圖1所示)
兩位參加遊戲的法師分別指揮某個小和尚向上走任意多級的台階,但會被站在高階台階上的小和尚阻擋,不能越過。兩個小和尚也不能站在同一台階,也不能向低階台階移動。
兩法師輪流發出指令,最後所有小和尚必然會都擠在高段台階,再也不能向上移動。輪到哪個法師指揮時無法繼續移動,則遊戲結束,該法師認輸。
對於已知的台階數和小和尚的分布位置,請你計算先發指令的法師該如何決策才能保證勝出。
輸入格式
輸入資料為一行用空格分開的n個整數,表示小和尚的位置。台階序號從1算起,所以最後乙個小和尚的位置即是台階的總數。(n<100, 台階總數<1000)
輸出格式
輸出為一行用空格分開的兩個整數: a b, 表示把a位置的小和尚移動到b位置。若有多個解,輸出a值較小的解,若無解則輸出-1。
樣例輸入
1 5 9
樣例輸出
1 4樣例輸入
1 5 8 10
樣例輸出
1 3說一些似懂非懂的理解......
首先這個題目,可以把它抽象成取球模型。
想法1:最高層的人對應的堆個數為0,第二層對應的堆的個數為和上一層高度差-1(題目要求同台階不站人)。於是我們可以把題目看成取這些堆,每次拿走任意多個,變成乙個一般的尼姆博弈問題。然而( ° △ °|||)。。。我們忽略了一點,題目要求下層的人不能越過上層的人,而一般的取球模型並沒有這個約束(堆之間的大小關係不能變動),如果把模型抽象成這樣,對我們每次取球的個數加上了限制。( ̄ε(# ̄)
在上圖中,我們可以將a-b、c-d間的距離當成尼姆堆:
a.如果當前是奇異局勢,先手將b上移x,那麼後手可以追隨將a上移x,使得先手再度面臨奇異局勢。如果先手將a上移動,我們也可以將c上移使得最後抑或出來結果依舊為0,依舊是奇異局勢。
b.如果不是奇異局勢,那麼先手讓後手面臨奇異局勢即可勝利。
總之分析問題不要太重過程,在上述分析中我們並沒有深刻地討論具體移動的步驟,我們只是抽象出了那些會影響勝負的因素罷了。
ac**:
#include
using namespace std;
int arr[105],rest[105];
int main()
n--;//總數
for(i=2;i<=n;i+=2)
if(!res)
else if(n<=3)
else
res^=temp;
res^=rest[cnt];}}
}return 0;
}
簡單博弈論
這道題目的意思就是說給你乙個n m的格仔,每次只能從右上角出發,只能往下,往左,往左下角走,每次只能走一步,誰不能走了,誰就輸。其實就是誰先到達左下角,誰就贏了,輸出先手kiki的輸贏情況。這道題的ac 特別簡單,將n和m乘起來,判斷奇偶,然後輸出即可,第一次做的時候,沒反應過來就過了,現在補充一下...
演算法 簡單博弈論
僅有一堆n個物品,兩個人輪流取1 m個,最後取的人勝 不能取的人輸 總體可分幾種情況 int bash game int n,int m 是否先手有必贏策略 將一堆變為多堆 即 有3堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取1個,多者不限,最後取光者得勝。本部分含其他部落格內容...
博弈論(sg)簡單題
鐵子和順溜在學習了博弈論的sg函式之後,解決了很多很多博弈題,現在他們遇到了一道難題。給出乙個長度為 n 的數列,數列裡的每個元素都是個位數,這個數列的每乙個連續子數列都能生成 乙個十進位制數,對於子數列a l r 這個十進位制數的個位為a r 十位為a r 1 最高位 為a l 現在鐵子需要知道最...