原文链接:http://hi.baidu.com/king___haha/item/542a071140107f9598ce337c

fib[1..]={1,2,3,5,8,13,21,...};是菲波那契数列,fib[]<=1000
每次只能取 fib[i]个

1. 如果只有1堆m个,m是某个fib[i],m是必胜点,m=1,2,3,5,8,13,21,...是必胜点
易知0,4 是必败点.如果从m个中取走 k个(k=fib[i]) ,m-k是必败点
则 m是必胜点.

6-2=7-3=9-5=4是必败点, 6,7,9 是 必胜点

m=10,m-1=9,m-2=8,m-3=7,m-5=5,m-8=2

从m=10中所有取法后都是必胜点 ==> m=10是必败点

这样当只有1堆时我们可以求所有必败点,用 w[1001]表示,w[i]=0表示i是必败点
w[i]=1表示i是必胜点,
w[0]=0;w[1]=w[2]=w[3]=1;
for(i=4;i<=1000;i++)
{
   for(j=1;fib[j]<=i;j++) if(w[i-fib[j]==0){w[i]=1;break;}

//取所有的Fibonacci数都胜,则该点必败

if(fib[j]>i)w[i]=0;
}

只有1堆时所有必败点:
0 4 10 14 20 24 30 36 40 46 50 56 60 66 72 76 82 86 92 96 102 108 112 118 122 128
132 138 150 160 169 176 186 192 196 202 206 212 218 222 228 232 238 242 248 254
260 264 270 274 280 284 290 296 300 306 310 316 322 326 332 338 342 348 352 358
364 368 374 378 384 388 394 400 406 410 416 420 426 430 436 442 446 452 456 462
468 472 478 484 488 494 498 504 510 514 520 524 530 534 540 552 556 562 566 572
576 582 588 592 598 602 608 618 635 644 662 672 688 694 698 704 708 714 723 730
734 740 750 754 766 772 776 782 791 798 808 814 818 824 830 834 840 844 850 854
860 866 872 876 882 886 892 896 902 908 912 918 922 928 934 938 944 950 954 960
964 970 976 980 986 990 996 1000

2. 有2堆m个和 n个

如果 m和 n都是 (1堆的)必败点,则2堆 (m,n) 也是必败点
一般 有 必败+必败=必败, 这里+不是把2队合为1堆
          必败+必胜=必胜

必胜+必胜=?不一定

例如 2堆   (4,10) 是必败

(4, 5) 是必胜

易知 ( m,m )必败

定义: 如果 (m,n) 必败,则称 m和n等价
   等价是相等的推广:m=n,    m和n等价
   
   只有1堆时所有必败点都和0等价,我们说只有1堆时所有必败点是第0类的或他的等价类数是0;

2堆 (1,5) 是必败的,5和1等价,和1等价的m叫做他的等价类数是1

2堆时的情况用 w2[m1][m2] 表示,w2[m1][m2]=0表示 (m1,m2)必败,
   w2[m1][m2]=1表示 (m1,m2)必胜
   
   用前面方法可算出等价类数是1的数,例如 1,5,11的等价类数是1

可以进行等价代换例如 3堆 1,5,7 可代换为 1,1,7,是必胜的

3. 结论(不证明了) 如果算出 m,n,p的等价类数是,E[m],E[n],E[p]

令 s=E[m]^E[n]^E[p]

则 s=0 是必败点

等价类数的算法
E[0]=0;

等价类数 E[i] 的算法:从i个中取走 fib[1],fib[2],...,fib[j]<=i   个后剩下

i-fib[1], i-fib[2],..., i-fib[j]个

他们的等价类数中没有出现的最小数就是i的等价类数

例如 i=1,取走fib[1]=1个 i-fib[1]=0,0的等价类数是0,没有出现的最小数就是1

E[1]=1;

例如 i=2,取走fib[1]=1个 i-fib[1]=1,取走fib[2]=2个 i-fib[1]=0,
   1和0的等价类数是1,0,没有出现的最小数就是2

E[2]=2;

例如 i=3,取走fib[1]=1个 i-fib[1]=2,取走fib[2]=2个 i-fib[1]=1,取走fib[3]=3个 i-fib[1]=0,
   2,1和0的等价类数是2,1,0,没有出现的最小数就是3

E[3]=3;

例如 i=4,取走fib[1,2,3]=1,2,3个 剩下3,2,1,没有出现的最小数就是0

E[4]=0;   4是必败点

例如 i=5,取走fib[1,2,3,4]=1,2,3,5个 剩下4,3,2,0,等价类数是 0,3,2,0没有出现的最小数就是1

E[5]=1;

//计算等价类数
E[0]=0;E[1]=1;
for(i=2;i<=1000;i++)
{ //首先假设 i<=1000时 等价类数<=15

for(j=0;j<=15;j++)h[j]=0;// h[j]==0, j没有出现,h[j]=1,j出现
for(j=1;fib[j]<=i;j++)
{
   h[ E[i-fib[j]] ]=1;

}
for(j=0;j<=15;j++)if(h[j]==0){E[i]=j;break;}//h[j]=0,j没有出现
}

因此计算步骤是:
1.计算菲波那契数列fib[i],计算到 fib[i]>1000为止
2.计算等价类数 E[i]
3. 同上面的 3

#include <iostream>
using namespace std;
int fib[1005],e[1005],h[20];
void Fib()//求Fibonacci数。
{fib[1]=1;fib[2]=2;for(int i=3; i<=16; i++)fib[i]=fib[i-1]+fib[i-2];
}
void E()
{e[0]=0;e[1]=1;int k;for(int i=2; i<=1000; i++){for(int j=0; j<=15; j++) h[j]=0;//将H全部初始化为0for(int j=1; fib[j]<=i; j++)h[e[i-fib[j]]]=1;//标记读过的的数列/*i-Fib[j]为下一步可能到达的子局面或者说是可能出现的情况例如i=9时,出现的情况为{8,7,6,4,1} E[i-Fib[j]]则表示此时的等价类数或者说是SG函数值 H[E[i-Fib[j]]]=1则是读过的数标记为1,要读的数为1~i 。接下来我们看下面一个for循环 */ for(int j=0; j<=15; j++)if(!b[j]){e[i]=j;break;}}
}//求等价类数。
int main()
{int m,n,p;while(cin>>m>>n>>p){if(m==0&&n==0&&p==0)break;Fib();E();int a=e[m],b=e[n],c=e[p];a=a^b^c;if((e[m]^e[n]^e[p])==0)cout<<"Nacci"<<endl;elsecout<<"Fibo"<<endl;}return 0;
}



												

HDU 1848(SG函数应用)相关推荐

  1. HDU 1848 SG函数

    这题运用博弈中的SG函数解决的,感觉初级博弈题用这个很好用但是难一些的还是不会求SG值,就是SG的模板题. #include <iostream> #include<cstdio&g ...

  2. 博弈论与sg函数入门

    记录一点结论性的东西,推导见百度吧. 首先博弈的前提是双方"绝对理智". 一般的胜负博弈游戏来说,有以下几点:(注意必胜必败是针对这回合操作的人) 所有终结状态为必败点(比如五子棋 ...

  3. SG函数入门HDU 1848

    SG函数 sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3. ...

  4. Fibonacci again and again HDU - 1848(尼姆博弈+SG函数的运用+SG函数详解)

    题意: 给出三堆石子(m,n,p个),两人每次只能取斐波那契数f[i]个,最先取光所有石子者取胜 题目: 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义 ...

  5. HDU 1846-Brave Game(巴什博弈-SG函数)

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. HDU - 1536 S-Nim(sg函数)

    题目链接:点击查看 题目大意:根据尼姆博弈的规则,现在更改为每次只能从任意一堆中取走规定集合中的数目,问每次游戏先手必胜还是必败 题目分析:sg打表模板题,这里挂一个大牛的博客,讲得是尼姆博弈和sg函 ...

  7. HDU - 1079 Calendar Game(博弈打表sg函数)

    题目链接:点击查看 题目大意:给出一个日期,两个人轮流按照规则操作,具体规则如下: 每次可以增加一天 每次可以增加一个月到下一个月的当天 首先到达2001年11月4日的人获胜,问谁能获胜 题目分析:因 ...

  8. hdu 1848(Fibonacci again and again)(SG博弈)

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  9. HDU 1404 Digital Deletions(博弈 + SG函数打表)

    Digital Deletions 思路 一道博弈论的题目,考虑到题目所给的范围是字符长度为1−>61-> 61−>6,所以我们可以考虑暴力打表出10610 ^ 6106内的所有状态 ...

  10. *【HDU - 1517】【POJ - 2505】A Multiplication Game(博弈,递推找规律或SG函数)

    题干: Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers ...

最新文章

  1. linux+离线+搜狗,Ubuntu离线安装Sogou拼音(附老版本安装)
  2. c++STL容器的Map和multimap
  3. elementui ts vant冲突_如何解决vue多个ui框架css冲突?
  4. (一)Rational Rose 2007 下载安装
  5. plsql 存储过程 批量提交_Spring Batch 批量处理策略
  6. CCF201612-1 中间数(解法二)(100分)(废除!!!)
  7. 2019JAVA面试题精粹附答案
  8. 微信小助手简版 WeChatSeptet for Mac安装教程!
  9. 雷迪9000使用说明_雷迪操作手册
  10. python基金比较上机题_使用python筛选基金
  11. 迁移学习对医疗图像的影响(Transfusion: Understanding Transfer Learning for Medical Imaging)
  12. 面试题(19)今日头条Java后台研发三面题目
  13. php函数几种写法,PHP让人不知道的匿名函数的几种写法(附代码)
  14. 管理经济学知识点汇总
  15. 用java构造圆类_JAVA实验报告(圆类.doc
  16. 基于FPGA实现的流水灯实验
  17. 粤语正字最新修正版(绝对权威)
  18. 非静态的字段、方法或属性 要求对象引用
  19. WinDbg调试:启动和退出
  20. 【keil5】keil官网PACK包不显示的解决方案

热门文章

  1. 关于计算机f开头的英语,f开头的英文有哪些
  2. 11. K8S资源限制,多账户管理及网络实现
  3. switchresx卸载_SwitchResX
  4. 向量空间模型——计算文本(英文)相似度
  5. 智能图像处理技术:开启未来视觉时代
  6. 5分钟了解系统架构设计
  7. JVM-监控及诊断工具
  8. Tensorflow执行PB模型问题
  9. 推荐系统Python代码实现
  10. BP神经网络原理与异或实例分析