HDU 1848 Fibonacci again and again (sg函数,博弈论)

Posted hhlya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1848 Fibonacci again and again (sg函数,博弈论)相关的知识,希望对你有一定的参考价值。

题面

Problem Description
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3);
所以,1,2,3,5,8,13……就是菲波那契数列。
在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
1、 这是一个二人游戏;
2、 一共有3堆石子,数量分别是m, n, p个;
3、 两人轮流走;
4、 每走一步可以选择任意一堆石子,然后取走f个;
5、 f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、 最先取光所有石子的人为胜者;

假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。

Input
输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
m=n=p=0则表示输入结束。

Output
如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。

Sample Input
1 1 1
1 4 1
0 0 0

Sample Output
Fibo
Nacci

思路

这是道关于sg函数和博弈论的入门题。在了解sg函数之前,我们也有必要了解一下博弈论的几个经典模型。包括威佐夫博弈,巴什博奕,斐波那契博弈,尼姆博弈等,首先最简单的巴什博奕,那么先手只需要根据n%(m+1)得出的s去取就可以了,反之如果这个s不存在,那么先手必输。斐波那契博弈的话,在巴什博奕的条件上加上了一个两倍条件的限制,那么结论就是如果我当前的先手面对的是一个非斐波那契数,那么先手必胜,反之后手胜。尼姆博弈:扩展到了s堆,我们这个只需要去求取所有堆的数目的异或值,如果这个值是非负的,那么先手必胜,反之后手胜。威佐夫博弈的话,先手必败,当且仅当黄金分割数*(y-x)=x。那么我们来讲一下sg函数,它的实际用处就是来解决一些不那么典型的博弈论的题目,就是对尼姆的一个抽象概括吧。我们标记0为必败态,从0出发构建向上构建每一个状态的sg值,那么sg值等于我所以可能扩展到的sg的mex值,mex是指不在集合中的最小自然数,这样我们就可以达到对每个状态都判断出必胜或者必败。当我的后继状态有一个为0时,我这个状态就是一个必胜态,因为我足够聪明。所以这个构建完成一张有向无环图之后,我们标记所有出发点,去这些点的sg值的异或,先手必胜当且仅当这个值不等于0。至于为什么这个组合状态会等于这些状态的异或值,这个需要用数学归纳证明,这里就不赘述了。

代码实现

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=1010;
int sg[maxn],mex[maxn],fib[24];

int main () {
    int n,m,p;
    fib[1]=1; fib[2]=2;
    for (int i=3;i<=1010;i++) fib[i]=fib[i-1]+fib[i-2];

    for (int i=1;i<=maxn;i++) {
        memset (mex,0,sizeof (mex));
      for (int j=1;fib[j]<=i;j++) {
          mex[sg[i-fib[j]]]=1;
      }

      for (int j=0;j<=maxn;j++) {
          if (!mex[j]) {
              sg[i]=j;
              break;
          }
      }
    }

    while (cin>>n>>m>>p) {
        if (n==0&&m==0&&p==0) break;
        if (sg[n]^sg[m]^sg[p]) cout<<"Fibo"<<endl;
        else cout<<"Nacci"<<endl;
    }




    return 0;
}





















以上是关于HDU 1848 Fibonacci again and again (sg函数,博弈论)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1848 Fibonacci again and again

HDU1848 Fibonacci again and again(SG函数)

hdu 1848 Fibonacci again and again(SG函数)

HDU 1848(sg博弈) Fibonacci again and again

HDU1848Fibonacci again and again(博弈论)

题解报告:hdu 1848 Fibonacci again and again(尼姆博弈)