威佐夫博弈

定义

威佐夫博弈(Wythoff's game):有两堆各若干个物品,两个人轮流从任一堆取至少一个或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

思路

看到题目首先拿出看家绝活打表

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e3+5,inf=0x3f3f3f3f,mod=1e9+7;
const int eps=1e-3;
int n;
int dp[maxn][maxn];
signed main(){
    scanf("%d",&n);
    dp[0][0]=0;
    int  last=0;
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            for(int k=1;k<=min(i,j);k++){
                dp[i][j]|=(!dp[i-k][j-k]);
            }
            for(int k=1;k<=i;k++){
                dp[i][j]|=(!dp[i-k][j]);
            }
            for(int k=1;k<=j;k++){
                dp[i][j]|=(!dp[i][j-k]);
            }
            if(dp[i][j]==0&&i<=j){
                cout<<i<<" "<<j<<endl;
            }
        }
    }
    return 0;
}
//(0,0),(1,2),(3,5),(4,7),(6,10)

打出所有必败态

这个时候你会发现差值是0,1,2,3...逐步递增

对于正常人来说还是没什么思路......所以看题解

首先说一些性质

你观察会发现

任何自然数都包含在一个且仅有一个必败态中

显然地,全体正整数被必败态分割成两个不相交的集合。

这个时候可以想到beatty定理

设a、b是正无理数且 1/a +1/b =1。
记P={ [na] | n为任意的正整数},Q={ [nb] | n 为任意的正整数},([x]指的是取x的整数部分)则P与Q是N+的一个划分,即P∩Q=Ø且P∪Q=N+(正整数集)

设第一个数为\(\lfloor a*n\rfloor\) 则第二个数为\(\lfloor a*n+n\rfloor\)

因为差值为n

带入式子

\(\frac{1}{a} + \frac{1}{a + 1} =1\)

\(a^2-a-1=0\)

\(a=\frac{1+\sqrt 5}{2}\)

那么如果这是必败态则第二个数减第一个数乘a=第一个数

模板题

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e3+5,inf=0x3f3f3f3f,mod=1e9+7;
const double rat=(sqrt(5)+1)/2;
int a,b;
signed main(){
    scanf("%d%d",&a,&b);
    if(a<b) swap(a,b);
    if((int)((a-b)*rat)!=b){
        printf("1\n");
    }else{
        printf("0\n");
    }
    return 0;
}
//(0,0),(1,2),(3,5),(4,7),(6,10)

参考链接:

https://www.luogu.com.cn/blog/KonjacWyx/solution-p2252

https://baike.baidu.com/item/威佐夫博弈/19858256?fr=aladdin

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/14395899.html