博弈_Poj_1067

//很深奧啊 勉強看懂了原理,以後再多看幾遍慢慢消化吧
//這裏就先把根據以下原理A掉的代碼貼一下

#include<iostream>
#include<cmath>
using namespace std;
int x,y;
int main()
{
double a = (sqrt(5.0)+1)*1.0/2;//黃金分割比
double b = a+1;//分割中的另一個底數
int k;
while(cin>>x>>y)
{
k=(x+1)*1.0/a;
if((int)(a*k-x)==0 && (a*k-x)>0)//a如果屬於第一列
{
if((int)(k*b-y)==0 && (k*b-y)>0)//b剛好屬於第二列,輸
printf("0\n");
else printf("1\n");//否則贏
}
else
{
k=(x+1)*1.0/b;
if((int)(k*a-y)==0 && (k*a-y)>0)//a不屬於第一列(屬於第二列),如果b屬於第一列,輸
printf("0\n");
else printf("1\n");//否則贏
}
}
return 0;
}

以下內容轉來的:

首先回顧必勝態和必敗態的樸素求法:

定理 0:一個狀態是必敗態,當且僅當它的所有後繼狀態都是必勝態;而一個狀態是必勝態,只要它的後繼狀態有一個以上的必敗態即可。

證明略去。

容易發現下面的定理:

定理 1:(a,b) 和 (b, a) 的勝負性是相同的(a <> b)。

證明:如果 (a, b) 是必勝態,那麼將必勝策略中所有的操作,對第一堆的變爲第二堆,對第二堆的變爲第一堆,就構成 (b, a) 的必勝策略

定理 2:若 (a, b) 是必敗態,則對於所有的 x <> a 和 y <> b,(x, b) 和 (a, y) 是必勝態。

證明:

對於 x > a 和 y > b,不管是哪一種情況,總可以從 x 堆或 y 堆中取出一定量的石子使當前狀態變爲必敗態 (a, b),由定理 1,(x, b) 和 (a, y) 爲必勝態。

對於 x < a 和 y < b,不管是哪一種情況,如果 (x, b) 或 (a, y) 是必敗態的話,由上述可得 (a, b) 是必勝態,矛盾。故 (x, b) 和 (a, y) 均爲爲必勝態。

定理 3: 若 (a, b) 是必敗態,則對於所有的 d > 0,(a + d, b + d) 是必勝態。

證明:

與定理 2 類似。

定理 4:在所有的必敗態中,每個數字恰巧出現一次。

證明:

有了定理 1,對於對稱的狀態我們只需要處理其中一個,而兩個數不會相同(相同的狀態必然是必勝態),於是我們把每個狀態中較小的數字放在前面,每行寫一個狀態,去掉括號並按照升序排列每行的第一個數,就構成了如下的矩陣:

1 2

3 5

4 7

6 10

……

觀察這個矩陣,我們又可以得到新的定理:

定理 5:矩陣中每行第一個數恰巧是前面每一行中沒有出現過的最小正整數。

證明:

由定理 4,矩陣中每個數字恰巧出現一次,而按照這個矩陣的定義,第二列的數總比同行第一列大,第一列又按照升序排列,所以每一行的第一個數正好爲前面每一行中沒有出現過的最小正整數。

定理 6:矩陣第 i 行的第二個數正好爲第一個數加上 i

證明:

用數學歸納法。

1) 對於第一行顯然成立

2) 若對於前 i - 1 行均成立,則所有的 (a[p], a[p] + p) (a[p] 爲第 p 行第一個數,p < i) 均爲必敗態,那麼考察第 i 行的狀態 (a[i], a[i] + delta)。容易看出 delta >= i,因爲如果 delta < i,一定可以通過一次操作變爲前面出現過的必敗態,那麼這個狀態就是必勝態。下面由 delta >= i,我們來說明 delta = i。

首先,我們考慮從第一堆中取出 p 個石子,得到狀態 (a[i] - p, a[i] - p + delta),由定理 5,比 a[i] 小的數都在之前出現過,若 a[i] - p 出現在某一行的第一列,由於存在必敗態 (a[i] - p, a[i] - p + d) (d < delta),故 (a[i] - p, a[i] - p + delta) 一定爲必勝態(定理 2);若 a[i] - p 出現在某一行的第二列,由於第一列是單增的,因而其對應的第一列數必小於 a[i] + delta,故而也可推出其狀態爲必勝態。

對於從兩堆石子中取出相同數目的情況與之類似,容易看出一定爲必勝態。

於是,(a[i], a[i] + delta) 狀態的勝負性只與狀態 (a[i], a[i] + d) (d < delta) 有關。不難看出,delta = i 時恰爲必敗態,因爲不論從第二堆中取出多少個石子,作爲另一堆的第一堆石子並沒有在之前出現過,所以得到的一定是一個必勝態,因而 (a[i], a[i] + delta) 爲必敗態,由定理 2 及定理 4 可得,原命題成立。即矩陣中第 i 行第二列的數等於同行第一列的數加上 i。

這時,我們所有的問題都轉化到了矩陣上,只要能通過合適的方法表示出這個矩陣,我們就可以很好地解決原問題。

下面的過程可能需要比較高的數學技巧,首先給出我們需要的一個重要定理([x] 表示 x 的整數部分,{x} 表示 x 的小數部分,即 {x} = x - [x]):

定理 7(Betty 定理):如果存在正無理數 A, B 滿足 1/A + 1/B = 1,那麼集合 P = { [At], t  Z+}、Q = { [Bt], t  Z+} 恰爲集合 Z+ 的一個劃分,即:P  Q = Z+,P  Q = ø。

證明:暫時略去,將來補充。

考慮到 Betty 定理中“恰爲 Z+ 的劃分”這一說,這意味着,Z+ 中的每個數都恰好出現一次,這與上述矩陣的性質十分吻合。於是我們猜想每一行第一列的數滿足 [Φi] 的形式。

於是我們得到每一行第二列的數爲 [Φi] + i = [Φi + i] = [(Φ + 1)i]

我們的目的是要讓 Z+ 中每個數都在這個矩陣中出現,於是考慮到 Betty 定理的條件,Φ 和 (Φ + 1) 應滿足 1/Φ + 1/(Φ + 1) = 1。解這個方程,我們得到 Φ = (sqrt(5) + 1) / 2,於是 Φ + 1 = (sqrt(5) + 3) / 2。

Φ 恰爲黃金分割比,這是多麼令人驚奇的結論!

於是應用 Betty 定理,我們得到最終我們需要的定理:

定理 8:上述矩陣中每一行第一列的數爲 [Φi],第二列的數爲 [(Φ + 1)i],其中 Φ = (sqrt(5) + 1) / 2 爲黃金分割比。

證明:由 Betty 定理顯然得證。

附:貝蒂定理證明……想了一會,還是Google了一下


設a、b是正無理數且 1/a +1/b =1。記P={ 【na】 | n爲任意的正整數},Q={ 【nb】 | n 爲任意的正整數},則P與Q是Z+的一個劃分,即P∩Q爲空集且P∪Q爲正整數集合Z+。
 證明:因爲a、b爲正且1/a +1/b=1,則a、b>1,所以對於不同的整數n,【na】各不相同,類似對b有相同的結果。因此任一個整數至多在集合P或Q中出現一次。

 * 現證明P∩Q爲空集;(反證法)假設k爲P∩Q的一個整數,則存在正整數m、n使得【ma】=【nb】=k。即k < ma、nb<k+1,等價地改寫不等式爲

 * m/(k+1)< 1/a < m/k及n/(k+1)< 1/b < n/k。相加起來得 (m+n)/(k+1) < 1 < (m+n)/k,即 k < m+n < k+1。這與m、n爲整數有矛盾,所以P∩Q爲空集。現證明Z+=P∪Q;已知P∪Q是Z+的子集,剩下來只要證明Z+是P∪Q的子集。(反證法)假設Z+\(P∪Q)有一個元素k,則存在正整數m、n使得【ma】< k <【(m+1)a】、【nb】< k <【(n+1)b】。 由此得ma < k ≦【 (m+1)a】-1<(m+1)a -1,類似地有nb < k ≦【 (n+1)b】-1<(n+1)b -1。等價地改寫爲 m/k < 1/a < (m+1)/(k+1)及n/k < 1/b < (n+1)/(k+1)。兩式加起來,得

 (m+n)/k < 1 < (m+n+2)/(k+1),即m+n < k < k+1 < m+n+2。這與m, n, k皆爲正整數矛盾。所以Z+=P∪Q。
感謝某位大人的博客(當時直接粘到google note上了,沒注意是誰)以及好像是維基百科……對想到用貝蒂定理的大神orz

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章