1. 程式人生 > >博弈遊戲之三大博弈

博弈遊戲之三大博弈

奇異局勢(必敗態)

博弈是不公平的遊戲  因為只要雙方足夠聰明   從遊戲開始就已經確定了結果

在我們的博弈遊戲中 想獲取勝利  就要尋找必輸狀態

要尋找必敗狀態 首先要知道什麼情況下算輸

在遊戲規則下  輪到你了卻無法進行操作 就認定為輸了(這是遊戲的前提)

然後 我們尋找必敗態

想一下  如果你面對必敗態  那麼你做任何操作  都將會把局面轉化為非必敗態(如果你能轉化為必敗態  你對手豈不是輸了~~~~~那你就不是必敗了)

那麼你只能轉化為非必敗態  你的對手面對非必敗態一定可以將其轉化為必敗態(這樣才能保證你必敗~~)

綜上   --在一個存在必輸局面和必贏策略的遊戲中  一定滿足以下性質

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我們要找的奇異局勢 必敗狀態