簡單博弈論

2021-07-15 12:07:48 字數 1520 閱讀 8615

這道題目的意思就是說給你乙個n*m的格仔,每次只能從右上角出發,只能往下,往左,往左下角走,每次只能走一步,誰不能走了,誰就輸。其實就是誰先到達左下角,誰就贏了,輸出先手kiki的輸贏情況。

這道題的ac**特別簡單,將n和m乘起來,判斷奇偶,然後輸出即可,第一次做的時候,沒反應過來就過了,現在補充一下詳細的解釋,博弈論分析問題常用n,p兩種狀態分析,

p表示必敗點,誰處於此位置,則在雙方操作正確的情況下必敗。

n表示必勝點,處於此情況下,雙方操作均正確的情況下必勝。

現在我們一步一步的分析

假設1 * 1,很明顯這是必敗點(定義為從這裡出發),因為根本無路可走

假設2 * 1,這是必勝點,當你從這裡出發的時候,對手位於1 * 1這個必敗點,相對的你就贏了

假設2 * 2,這是必勝點,理由同上

一步一步這樣分析,就可以畫出這樣的圖

由此可以看出,實際上當n * m為奇數是必敗點,所以**如下:

int n, m;

while(cin >> n >> m)

這道題目也是基本的取石子遊戲,意思是現在有m堆石子,每次可以從任意一堆裡面取走任意多的石子(當然不能不取或者超過這堆石子的最大指),誰不能取了誰就輸,判斷先手的輸贏情況,當然保證兩名選手都足夠聰明(要不不保證,取石子遊戲就沒有意思了。。。。)。

這道題當然可以使用sg定理直接求解,而且還特別簡單,因為每堆石子的sg值就是它自身,即sg(x) = x,因為這堆石子,你取走以後剩下0, 1, 2 ... x - 2, x - 1.所以sg(x) = mex(sg[0], sg[1], sg[2], .....sg[x-2], sg[x-1]) = x;

所以這道題都不需要打表了,直接異或累起來,判斷是否非零即可,**如下:

int main()

if(!ans)

cout << "no" << endl;

else

cout << "yes" << endl;

}return 0;

}

記得小時候玩的乙個遊戲,兩個人輪流報數,每次只能報乙個或者兩個,誰先報道30誰就贏,不就是和這個題目一模一樣的,想起來那時候學會這個規則,戰無不勝啊,哈哈,這個就是巴什博奕,有一句話就是「加一整除,先手必輸」,比如上面說的30個數字,也就是題幹的30個石頭,每次取不能超過2個,只要對手先取石子,我只需要保證我取得數字恰好能整除即可,比如他拿1 2,我就拿3;他拿4,我就拿5 6。這樣下去,我永遠抓住這個倍數,那麼最後肯定是我贏。

**如下:

int main()

return 0;

}

簡單博弈論

1.巴什博弈 問題描述一般為,有一堆物品,有n個,a b輪流從中取物,最少取乙個,最多取m個,規定取走最後一堆的人獲勝。對於博弈問題,首先需要分析的是它的必敗情況。由題目可知,假設當前的人a面對的物品堆已空,即為0時,就輸了,所以最基本的必敗為0。那麼根據取物品的取值為1 m,可以知道,在上一步b取...

演算法 簡單博弈論

僅有一堆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 現在鐵子需要知道最...