威佐夫博弈证明


最近在学博弈,写下威佐夫博弈的证明,巩固下对博弈的理解(奇异局势,NP状态,SG函数等)

题目大意

有两堆石子,两个人轮流取石子,有两种取法,一种是取一堆里的任意个,另一种是两堆同时取任意个,给出初始石子的数目,假设双方都采取最好的策略,问最后你是胜者还是败者。

思路分析

规定后手必胜态为奇异局势,且(0,0)为第0个奇异局势!!!
又因为(a,b)与(b,a)是一样的,所以令(x,y)中,x<=y。
接下来的奇异局势:
显然,(0,n)不是。(1,1)也不满足。
对于(1,2),先手一次不可能取完,而无论先手怎么取,后手都能一次取完。
因此(1,2)是接下来第一个奇异局势。
考虑到由奇异局势能够转移到的局势均不是奇异局势:
因此(0,0+n)、(0+n,0+n)、(1,2+n)、(1+n,2+n)均不是奇异局势(其中n∈Z+)
所以接下来的奇异局势应该是此前所有奇异局势无法转移到的第一个局势(第一个局势的意思就是对于局势(x,y),x要尽可能小,然后y也要最小)
∴y-x的值要尽可能小
∴y-x=mex{此前所有奇异局势的y-x} (否则就能由前面的奇异局势转移得到)
由数学归纳法易得:
第n个奇异局势(x,y)的y-x=n
记第n个奇异局势为(x,x+n)。
若x在此前奇异局势的x或y中出现,那就可以由此前奇异局势转移得来,显然不成立。
而若x不在此前奇异局势的x或y中出现,那就无法由由此前奇异局势转移得来。
又∵x要最小
∴x=mex{此前奇异局势出现过的x或y}
此时,若理论上可以一项一项地手动推出所有的奇异局势了,但x时而+1,时而+2,因此通项公式却仍然难以得到。

Betty定理

如果两个无理数a,b满足:

1 a \frac{1}{a} a1+ 1 b \frac{1}{b} b1=1

那么对于两个集合A,B:

A= { ⌊ n a ⌋ } \begin{Bmatrix} ⌊na⌋ \end{Bmatrix} {na},B= { ⌊ n b ⌋ } \begin{Bmatrix}⌊nb⌋ \end{Bmatrix} {nb},n ∈ \in Z+
存在以下两个结论:
A∩B=∅,A∪B=N+
在这里插入图片描述

通项推导

有了Betty定理,以及上面的结论
对于奇异局势(x,x+n)
根据Betty定理,x可被表示为⌊na⌋,y可被表示为⌊na⌋+n=⌊n(a+1)⌋
1 a \frac{1}{a} a1+ 1 a + 1 \frac{1}{a+1} a+11=1
a 2 − a + 1 = 0 a^2-a+1=0 a2a+1=0
∴a=​ 1 + √ 5 2 \frac{1+√5}{2} 21+5 1 − √ 5 2 \frac{1-√5}{2} 215<1舍弃)
所以第n个奇异局势就是( 1 + √ 5 2 \frac{1+√5}{2} 21+5n, 1 + √ 5 2 \frac{1+√5}{2} 21+5n+n) (取下整)

int main()
{
    int a,b;
    while(cin >> a >> b){
        if(a > b)swap(a,b);
        double tmp = (1.0+sqrt(5.0))/2;
        double n = b - a;
        if((int)(n * tmp) == a)cout << 0 << endl;
        else cout << 1 << endl;
    }
    return 0;
} 

扩展威佐夫博弈

给你两堆石子,每次可以单独拿一堆中的任意值,或者两堆都拿,但是两堆拿的值需满足∣ x − y ∣ ≤ d (d为给定常数)
从原来的y=x+n变为了y=x+nd
那么根据Betty定理,x可被表示为⌊na⌋,y可被表示为⌊na⌋+nd=⌊n(a+d)⌋
1 a \frac{1}{a} a1+ 1 a + d \frac{1}{a+d} a+d1=1
解得a=​ 2 − d + √ d ² + 4 2 \frac{2-d+√d²+4}{2} 22d+d²+4
所以第n个奇异局势就是(​ 2 − d + √ d ² + 4 2 \frac{2-d+√d²+4}{2} 22d+d²+4n,​ 2 + d + √ d ² + 4 2 \frac{2+d+√d²+4}{2} 22+d+d²+4n) (取下整)

int main() {
    ll a,b,d;
    int t;cin>>t;
    while(t--){
        cin>>a>>b>>d;
        d++;
        if(a>b)swap(a,b);
        ll n=(b-a)/d;
        double x=n*((sqrt(4.0+d*d)-d+2.0)/2.0);
        double y=n*((sqrt(4.0+d*d)+d+2.0)/2.0);
        if((int)x==a&&(int)y==b)cout<<0<<endl;
        else cout<<1<<endl;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

General.song

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值