HDU 2516 取石子游戏 斐波纳契博弈

斐波纳契博弈:

有一堆个数为n的石子,游戏双方轮流取石子,满足:

1)先手不能在第一次把所有的石子取完;

2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。

约定取走最后一个石子的人为赢家,求必败态。

证明 FBI数为必败局:

1.对于任意一个FBI数 FBI[K]=FBI[K-1]+FBI[K-2],我们可以将FBI[K]看成石子数目分别是FBI[K-1],FBI[K-2]的两堆(一定可以这样分,因为FBI[K-1] > FBI[K-2]*2,若先手取的数目大于等于FBI[K-2],则后手可以一次拿完)

2.将FBI[K-2],FBI[K-1],再次拆分,无论先手如何取,后手总能取走最后一个石子

证明 非FBI数为必胜局:

1.由齐肯多夫定理知道,任意一个整数,可以被拆分成几个不连续的FBI数相加的形式:n=FBI(ak)+FBI(ak-1)+FBI(ak-2)+……+FBI(a1)

2.因为式子中的FBI数不连续,所以FBI(a) > 2FBI(a-1)

3.先手取走FBI(a1)个石子,那么后手只能在FBI(a1+1)堆中取,且不能一次性取完。依旧是说对于任意一堆,总是先手取走最后一个石子!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define MAXSIZE 100005

using namespace std;

int fib[MAXSIZE];

int Game(int n)
{
    for(int i=1;i<=46;i++)
    {
        if(fib[i]==n)
            return 0;
    }
    return 1;
}

int main()
{
    int n;
    fib[1]=1;
    for(int i=2;i<=46;i++)
        fib[i]=fib[i-1]+fib[i-2];
    while(scanf("%d",&n),n)
    {
        int op=Game(n);
        if(op==0)
            printf("Second win\n");
        else
            printf("First win\n");
    }
    return 0;
}

时间: 2024-12-19 22:27:02

HDU 2516 取石子游戏 斐波纳契博弈的相关文章

HDU 2516 取石子游戏(斐波那契博弈)

题目地址:HDU 2516 当且只当n是一个斐波那契数的时候是必败态.可以写出几组数据找规律就可以发现这个规律. 证明如下: 就像"Wythoff博弈"需要"Beatty定理"来帮忙一样,这里需要借助"Zeckendorf定理"(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和. 先看看FIB数列的必败证明: 1.当i=2时,先手只能取1颗,显然必败,结论成立. 2.假设当i<=k时,结论成立. 则当i=k+1时,

取石子(斐波那契博弈)

题意:http://acm.hdu.edu.cn/showproblem.php?pid=2516 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win".先取者胜输出"First win". 1 #include<iostream> 2 using namespace std; 3 int main() { 4 int n, i,flag=1;

HDU 2516 取石子游戏(巴什博弈)

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2524    Accepted Submission(s): 1443 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&q

题解报告:hdu 2516 取石子游戏(斐波那契博弈)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2516 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win".先取者胜输出"First win". Input 输入有多组.每组第1行是2<=n<2^31. n=0退出. Output 先取者负输出"S

HDU 2516 取石子游戏 (斐波那契博弈)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2516 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win".先取者胜输出"First win". Input输入有多组.每组第1行是2<=n<2^31. n=0退出. Output先取者负输出"Second win". 先取者胜输

hdu 2516 取石子游戏

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2816    Accepted Submission(s): 1626 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&qu

HDU 2516 取石子游戏 (博弈论)

取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win".先取者胜输出"First win". Input 输入有多组.每组第1行是2<=n<2^31. n=0退出. Output 先取者负输出"Second win". 先取者胜输出"First win".

hdu 2516 取石子游戏 Fibonacci博弈 入门题

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3069    Accepted Submission(s): 1784 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&q

hdu 2516 取石子游戏 (Fibonacci博弈)

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8159    Accepted Submission(s): 4950 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&qu