斐波那契博弈

  首先有一个定理:齐肯多夫定理:任何整数可以分解成若干个不连续的斐波那契数之和

  斐波那契博弈游戏规则:一堆个数为n的石子,游戏双方轮流去石子。要求

    1)先手不能一次取完所有石子

    2)之后每次可以取的石子数介于1-对手刚取的石子数2倍之间

  定理:如果n不是斐波那契数,那么先手必胜,如果n是斐波那契数,那么先手必败(后手必胜)

  证明:n=fi + fi-1 + fi-2 ... + fi-k, 那么先手取fi-k,由于后手不能取大于等于fi-k*2的项,则n中剩下的斐波那契项,先手都可以取到最后一颗

  定理:那么若n是斐波那契数,则先手必败

  证明:设n=fi, fi=fi-1 + fi-2;先手取了x个石子

     x>=fi-2, 那么 fi - x <= fi - fi-2 = fi-1 = fi-2 + fi-3 < 2*fi-2,成立1

     x<fi-2,那么n-x分解成a个斐波那契数,且最小的斐波那契数<=2*x,局势转换成后手在n-x石子中先手,后手必胜

      (x<fi-2 反证):如果先手败,那么fi-2也是先手败,即后手取到最后一个,那么剩下的n-x,先手先取,先手必胜 -------矛盾

  总结:斐波那契数先手必败,非斐波那契数先手必胜

  hdu2516

#include<bits/stdc++.h>
using namespace std;
#define maxn 10000000000
#define ll long long 

map<ll,int>mp;
ll f[1000005];
void dabiao(){
    ll f3=2,f1=1,f2=1;
    mp[1]=1;
    while(f3<maxn){
        f3=f1+f2;
        mp[f3]=1;
        f1=f2,f2=f3;    
    }
}

int main(){
    dabiao();
    int n;
    while(scanf("%d",&n),n){
        if(mp[n]) puts("Second win");
        else puts("First win");
    }
}

  

原文地址:https://www.cnblogs.com/zsben991126/p/10202637.html