博弈遊戲之三大博弈
奇異局勢(必敗態)
博弈是不公平的遊戲 因為只要雙方足夠聰明 從遊戲開始就已經確定了結果
在我們的博弈遊戲中 想獲取勝利 就要尋找必輸狀態
要尋找必敗狀態 首先要知道什麼情況下算輸
在遊戲規則下 輪到你了卻無法進行操作 就認定為輸了(這是遊戲的前提)
然後 我們尋找必敗態
想一下 如果你面對必敗態 那麼你做任何操作 都將會把局面轉化為非必敗態(如果你能轉化為必敗態 你對手豈不是輸了~~~~~那你就不是必敗了)
那麼你只能轉化為非必敗態 你的對手面對非必敗態一定可以將其轉化為必敗態(這樣才能保證你必敗~~)
綜上 --在一個存在必輸局面和必贏策略的遊戲中 一定滿足以下性質
1、非必敗態一定可以移動到必敗態;
2、在必敗態做的所有操作的結果都是非必敗態。
(不是官方的定義 我自己總結的 幫助理解 如有不足 歡迎指正)
那麼我們找到的必敗態 最起碼要滿足這兩個性質。
巴什博弈-Bash Game
條件:
n 個物品堆成一堆。兩個人輪流從這堆物品中取,規定每次至少取一個,最多取 m 個。最後取光者得勝。(無法取者敗)
正解:
n大於m時 如果 n%(m+1)≠0 先手必勝
原理:
我們證明下 n%(m+1)=0 先手必敗
當輪到你拿的時候 如果 n是(m+1)的倍數 我們稱這種情況為奇異局 就是必敗局
簡單想一下 比如 有n=6 m=5 每次最多拿5個 你拿不完 而且不管你拿幾個 對手都可以拿完 取得勝利
而n=(m+1)*k時 是一樣的 每次不管你怎麼拿 你都不能保持局面是(m+1)的倍數(這就滿足了必敗態的性質2)
而你的對手每次都可以拿走幾個保持局面是 (m+1)的倍數(滿足了必敗態的性質1)
所以 n%(m+1)=0 先手必敗 不是(m+1)的倍數的時候 你只要拿走幾個讓局面變成奇異局就好了
威佐夫博奕Wythoff's game
條件:
威佐夫博弈(Wythoff's game):有兩堆各若干個物品,兩個人輪流從任一堆取至少一個或同時從兩堆中取同樣多的物品,規定每次至少取一個,多者不限,最後取光者得勝。
正解:
面對奇異局勢先手必輸。
如何判斷是不是奇異局勢:給你(a,b) a<b
k=b-a 如果 a =[k(1+√5)/2],b= a + k (方括號表示取整) 就是奇異局勢
解釋:
我們用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)(表示兩堆物品的數量並稱其為局勢,如果甲面對(0,0),那麼甲已經輸了,如果甲面對(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)都可以推出甲必輸。這一串數有什麼規律呢
(ai,bi) ai是前面未出現過的最小整數。bi=ai+k; k呢是這一串數的序號 第一個是0 然後是1 2 3.。。
同時k也是這幾對數每對數(a,b)的差值
這是我們找到的規律 是否就是我們要找的奇異局勢也就是必輸局面呢
我們證明一下
證明之前 我們先觀察我們發現的規律
很容易發現它有一個性質
任何自然數都包含在一個且僅有一個奇異局勢中。
ai是前面未出現過的最小整數。bi=ai+k;由這兩個規律, 從數學上可以證明此性質。
然後再看滿足我們說的規律的數 是否滿足必敗態的性質
滿足性質1、非必敗態一定可以移動到必敗態;
面對(a,b)一對數,只有 相等和不相等兩種情況。不管相等還是不相等,根據剛才提到的性質,都必然有一個數屬於一個奇異局勢,而我們只要對另一個數進行減法操作就可以使它變為奇異局勢。(主要是因為性質:.每個數,必然存在它對應的奇異局勢。)我們很容易變到奇異局勢。
滿足性質2、在必敗態做的所有操作的結果都是非必敗態。
根據性質1,若只改變奇異局勢(a[k],b[k])的某一個分量,那麼另一個分量不可能出現在其他奇異局勢中,所以必然是非奇異局勢。如果使(a[i],b[i])的兩個分量同時減少,則由於其差不變,且不可能是其他奇異局勢的差,因此也是非奇異局勢。(每個奇異局勢的差是唯一的)
所以符合我們規律的就是我們要找的必敗局面 奇異局勢
那麼我們只要判斷出符合我們找到的規律就行
bi=ai+k; k是(ai,bi)的差值 但是ai不好找
我們進一步發現規律 ai=[k*1.618]方括號代表取整。(0.618是黃金分割數,但是我們寫程式碼不能寫0.618,因為後邊還有小數需要精確,所以我們寫 (1+sqrt(5) )/2
1.618=(1+sqrt(5))/2
所以 結論是如果a =[k(1+√5)/2],b= a + k (方括號表示取整) 就是奇異局勢
程式碼
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long ll;
int T,n,m,a,b;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
a=min(m,n);b=max(m,n);
int k=b-a;
if(a==(int)( k*( 1+sqrt(5) )/2 ) )printf("B\n");
else printf("A\n");
}
return 0;
}
尼姆博弈 Nimm game
有三堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取一個,多者不限,最後取光者得勝。
正解
每堆物品的數量進行異或運算 結果等於0 就是奇異局勢 就是必敗態
原理
我們用(a,b,c)表示某種局勢,首先(0,0,0)顯然是奇異局勢,無論誰面對奇異局勢,都必然失敗。第二種奇異局勢是(0,n,n),只要與對手拿走一樣多的物品,最後都將導致(0,0,0)。仔細分析一下,(1,2,3)也是奇異局勢,無論對手如何拿,接下來都可以變為(0,n,n)的情形。
這些局勢都滿足 a^b^c=0
而異或運演算法則是 相同為0 不同為1 根據運演算法則 面對奇異局你不論怎麼拿 都不會還=0(滿足性質2)
而不滿足的a^b^c=0的局勢 我們都可以使其變成a^b^c=0
因為 局面(a,b,c) 我們只要令最大的數 比如是a 令a=b+c 就變成了 (b+c)^b^c=(b^b)+(c^c)=0(滿足性質1)
所以 a^b^c=0就是i我們要找的奇異局勢 必敗狀態