這道題目的意思就是說給你乙個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 現在鐵子需要知道最...