这篇虽然是转载的,但代码和原文还是有出入,我认为我的代码更好些。

转载自:http://www.cnblogs.com/frog112111/p/3199780.html

最新sg模板:

  1. //MAXN为所有堆最多石子的数量
  2. //f[]用来保存只能拿多少个 从0开始到num-1种情况 并且这里的f[]不需要排序
  3. const int MAXN = + ;
  4. int f[MAXN],sg[MAXN];
  5. bool vis[MAXN];
  6. void sgsol(int num,int N)
  7. {
  8. int i,j;
  9. memset(sg,,sizeof(sg));
  10. for(i=;i<=N;i++)
  11. {
  12. memset(vis,,sizeof(vis));
  13. for(j=;j<num;j++)
  14. {
  15. if (i-f[j]>=)
  16. vis[sg[i-f[j]]]=;
  17. }
  18. for(j=;;j++)
  19. if(!vis[j])break;
  20. sg[i]=j;
  21. }
  22. }

首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Grundy函数g如下:g(x)=mex{ g(y) | y是x的后继 },这里的g(x)即sg[x]

例如:取石子问题,有1堆n个的石子,每次只能取{1,3,4}个石子,先取完石子者胜利,那么各个数的SG值为多少?

sg[0]=0,f[]={1,3,4},

x=1时,可以取走1-f{1}个石子,剩余{0}个,mex{sg[0]}={0},故sg[1]=1;

x=2时,可以取走2-f{1}个石子,剩余{1}个,mex{sg[1]}={1},故sg[2]=0;

x=3时,可以取走3-f{1,3}个石子,剩余{2,0}个,mex{sg[2],sg[0]}={0,0},故sg[3]=1;

x=4时,可以取走4-f{1,3,4}个石子,剩余{3,1,0}个,mex{sg[3],sg[1],sg[0]}={1,1,0},故sg[4]=2;

x=5时,可以取走5-f{1,3,4}个石子,剩余{4,2,1}个,mex{sg[4],sg[2],sg[1]}={2,0,1},故sg[5]=3;

以此类推.....

x         0  1  2  3  4  5  6  7  8....

sg[x]      0  1  0  1  2  3  2  0  1....

计算从1-n范围内的SG值。

f(存储可以走的步数,f[0]表示可以有多少种走法)

f[]需要从小到大排序

1.可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);

2.可选步数为任意步,SG(x) = x;

3.可选步数为一系列不连续的数,用GetSG()计算

SG 打表 模板:

  1. //求[1,n]的sg函数值
  2. //f[0]:可以取的方案数 f[1]~f[n]每个方案可以取的石子数
  3. //sg[]:0~n的SG函数值 Hash[]:为了求最小非负整数
  4. const int N = + ;
  5. int f[N], sg[N], Hash[N];
  6. void SGsol(int n)
  7. {
  8. int i, j;
  9. memset(sg, , sizeof(sg));
  10. for(i = ; i <= n; i++)
  11. {
  12. memset(Hash, , sizeof(Hash));
  13. //这的j要小于f[0],因为只有f[0]种情况
  14. for(j = ; f[j] <= i && j <= f[]; j++)
  15. Hash[sg[i - f[j]]] = ;
  16. //求mes{}中未出现的最小的非负整数
  17. for(j = ;; j++)
  18. {
  19. if(Hash[j] == )
  20. {
  21. sg[i] = j;
  22. break;
  23. }
  24. }
  25. }
  26. }

hdu  1848

题意:

取石子问题,一共有3堆石子,每次只能取斐波那契数个石子,先取完石子者胜利,问先手胜还是后手胜

题解:

先把斐波那契存到f[]里,求1000以内的sg值,之后3个异或就好了。注意 异或的时候一定要加括号,因为^的优先级比==小,也就是说,不加括号,会先算==,之后再异或

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. const int N = + ;
  6. int f[N], sg[N], Hash[N], cnt;
  7. void SGsol(int n)
  8. {
  9. int i, j;
  10. memset(sg, , sizeof(sg));
  11. for(i = ; i <= n; i++)
  12. {
  13. memset(Hash, , sizeof(Hash));
  14. for(j = ; f[j] <= i && j < cnt; j++)
  15. Hash[sg[i - f[j]]] = ;
  16. for(j = ;; j++)
  17. {
  18. if(Hash[j] == )
  19. {
  20. sg[i] = j;
  21. break;
  22. }
  23. }
  24. }
  25. }
  26.  
  27. void Solve()
  28. {
  29. f[]=f[] = , f[] = , cnt = ;
  30. for(int i = ;; i++)
  31. {
  32. f[cnt++] = f[i - ] + f[i - ];
  33. if(f[i] > )
  34. {
  35. cnt--;
  36. break;
  37. }
  38. }
  39. SGsol(N);
  40. int a, b, c;
  41. while(cin >> a >> b >> c)
  42. {
  43. if(a + b + c == ) break;
  44. if((sg[a]^sg[b]^sg[c]) == ) puts("Nacci");
  45. else puts("Fibo");
  46. }
  47. }
  48.  
  49. int main()
  50. {
  51. Solve();
  52. return ;
  53. }

SG函数模板的更多相关文章

  1. hdu1536&&hdu3023 SG函数模板及其运用

    S-Nim Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status ...

  2. SG函数模板(转)

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

  3. hdu 1536 SG函数模板题

    S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  4. 【非原创】sg函数模板

    学习博客:戳这里 解题模型: 1.把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或.        即sg(G)=sg(G1)^sg(G2)^...^sg(Gn) ...

  5. Light OJ 1199:Partitioning Game(SG函数模板)

    Alice and Bob are playing a strange game. The rules of the game are: 1.      Initially there are n p ...

  6. HDU 1847-Good Luck in CET-4 Everybody!-博弈SG函数模板

    Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...

  7. hdu 1536 S-Nim(sg函数模板)

    转载自:http://blog.csdn.net/sr_19930829/article/details/23446173 解题思路: 这个题折腾了两三天,参考了两个模板,在这之间折腾过来折腾过去,终 ...

  8. SG函数 模板

    int get_SG(int x) { ) return SG[x]; ]={}; ;i<=n;i++) ) v[get_SG(x-s[i])]=; int i; ;v[i];i++); SG[ ...

  9. SG函数模板(洛谷2197nim游戏

    #include <iostream> #include <cstdio> #include <queue> #include <algorithm> ...

随机推荐

  1. Metasploit连接postgres数据库

    操作环境为Kali虚拟机 root@kali:~# apt-get install postgresql 启动服务 root@kali:~# service postgresql start [ ok ...

  2. ndk-build出错,错误以及解决办法如下

    用NDK编译jni目录下的文件了,我的系统是Ubuntu10.04,NDK版本是android-ndk-r7b. 切换到工程的jni目录下执行:ndk-build(ndk-build的路径已经添加到系 ...

  3. C中scanf/gets/fgets的区别

    功能:同样是获取字符串. 区别: scanf 遇到空格/回车/Tab键认为输入结束, 但是空格/回车/Tab键仍会留在输入的缓冲区中.常见的是使用getchar(),处理scanf的后事:如果想要清除 ...

  4. shell下的作业管理[转]

    作业管理 举例来说,我们在登陆 bash 后, 想要一边复制文件.一边进行数据搜寻.一边进行编译,还可以一边进行 vi 程序撰写! 当然我们可以重复登陆那六个文字介面的终端机环境中,不过,能不能在一个 ...

  5. JQuery之滑动幻灯片插件Easy Slider初体验

    Easy Slider 是一个滑动幻灯片插件,支持任何图片或内容,可以实现横向或纵向滑动.它拥有一系列丰富的参数设置,可通过CSS来进行完全的控制.基本上只需要引入这个插件后,设置好内容,然后样式化C ...

  6. cluster,network

    How cluster works https://technet.microsoft.com/en-us/library/cc738051(v=ws.10).aspx http://blogs.te ...

  7. 【Unity3D技巧】一个简单的Unity-UI框架的实现

    如何使用 请直接导入UnityUIFramework这个UnityPackage,然后进入名为Test的Scene即可开始体验各种特性,Enjoy!你可以通过访问我的Github进行查阅和下载. Vi ...

  8. android 完全退出应用程序(重要)

    android退出应用程序会调用android.os.Process.killProcess(android.os.Process.myPid())或是System.exit(0),这只是针对第一个A ...

  9. 墨刀 手机app原型工具

    https://modao.io 并且墨刀对开放项目永久免费!

  10. 【Reporting Services 报表开发】— 交互式报表

    我们知道,界面是人与系统间的对话方式,当使用者面对的是冷冰冰的界面,不但会造成使用者对于系统的热情减低,也会因为不便而产生诸多抱怨.尤其像报表时企业内几乎每日都会使用到的工具,因此,如何让使用者可以再 ...