博弈_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,对于对称的状态我们只需要处理其中一个,而两个数不会相同(相同的状态必然是必胜态),于是我们把每个状态中较小的数字放在前面,每行写一个状态,去掉括号并按照升序排列每行的第一个数,就构成了如下的矩阵:

2

5

7

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],  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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值