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

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

最新sg模板:

//MAXN为所有堆最多石子的数量
//f[]用来保存只能拿多少个 从0开始到num-1种情况 并且这里的f[]不需要排序
const int MAXN = + ;
int f[MAXN],sg[MAXN];
bool vis[MAXN];
void sgsol(int num,int N)
{
int i,j;
memset(sg,,sizeof(sg));
for(i=;i<=N;i++)
{
memset(vis,,sizeof(vis));
for(j=;j<num;j++)
{
if (i-f[j]>=)
vis[sg[i-f[j]]]=;
}
for(j=;;j++)
if(!vis[j])break;
sg[i]=j;
}
}

首先定义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,n]的sg函数值
//f[0]:可以取的方案数 f[1]~f[n]每个方案可以取的石子数
//sg[]:0~n的SG函数值 Hash[]:为了求最小非负整数
const int N = + ;
int f[N], sg[N], Hash[N];
void SGsol(int n)
{
int i, j;
memset(sg, , sizeof(sg));
for(i = ; i <= n; i++)
{
memset(Hash, , sizeof(Hash));
//这的j要小于f[0],因为只有f[0]种情况
for(j = ; f[j] <= i && j <= f[]; j++)
Hash[sg[i - f[j]]] = ;
//求mes{}中未出现的最小的非负整数
for(j = ;; j++)
{
if(Hash[j] == )
{
sg[i] = j;
break;
}
}
}
}

hdu  1848

题意:

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

题解:

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

#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int N = + ;
int f[N], sg[N], Hash[N], cnt;
void SGsol(int n)
{
int i, j;
memset(sg, , sizeof(sg));
for(i = ; i <= n; i++)
{
memset(Hash, , sizeof(Hash));
for(j = ; f[j] <= i && j < cnt; j++)
Hash[sg[i - f[j]]] = ;
for(j = ;; j++)
{
if(Hash[j] == )
{
sg[i] = j;
break;
}
}
}
} void Solve()
{
f[]=f[] = , f[] = , cnt = ;
for(int i = ;; i++)
{
f[cnt++] = f[i - ] + f[i - ];
if(f[i] > )
{
cnt--;
break;
}
}
SGsol(N);
int a, b, c;
while(cin >> a >> b >> c)
{
if(a + b + c == ) break;
if((sg[a]^sg[b]^sg[c]) == ) puts("Nacci");
else puts("Fibo");
}
} int main()
{
Solve();
return ;
}

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. Mac下的利器们介绍

    先说说一些快捷键吧,从windows下过来还不很习惯: ctrl + 开关 关机等提示 ctrl+shift+开关 关闭显示器 cmd+option+v 相当于剪贴 cmd+tab,对于最小化了的窗口 ...

  2. javase tutorial

    http://docs.oracle.com/javase/tutorial/index.html

  3. Python编程规范(PEP8)

    Python编程规范(PEP8) 代码布局 缩进 对于每一次缩进使用4个空格.使用括号.中括号.大括号进行垂直对齐,或者缩进对齐. 制表符还是空格? 永远不要将制表符与空格混合使用.Python最常用 ...

  4. myBatis 参数配置

    关于参数的类型 有四种类型: http://www.07net01.com/zhishi/402787.html 以上链接有所介绍,四种类型有:单个参数.多个参数.Map封装参数.List封装IN 如 ...

  5. 联表更新 Update Left Join

    Update a set a.Manage_FunctID=b.Manage_FunctID From Manage_PageUrl a Left join Manage_ButtonBar b on ...

  6. 写window应用程序日志System.Diagnostics.EventLog.WriteEntry

    System.Diagnostics.EventLog.WriteEntry( MySource , Writing to event log. ); 可以写window应用程序日志 查看的地方:右击 ...

  7. java_list,set,map集合

    一.集合定义 集合就是讲诺干用途相同.近似的“数据”结合成一个整体 集合从体系上分为三种 1.列表(List):List集合区分元素的顺序,允许包含相同的元素 2.集(set):Set集合不区分元素的 ...

  8. 007. 自定义ListBox的item的宽高, 字体居中

    /// <summary> /// 自定义ListBox的item的宽高, 字体居中 /// </summary> /// <param name="sende ...

  9. 04-Java 异常

    1.认识异常:异常是导致程序中断运行的一种指令流,如果不对异常进行正确处理,则可能导致程序的中断执行,造成不必要的损失. int a=10; int b=0; int temp=a/b; System ...

  10. qemu-kvm命令

    三种方式创建虚拟机 1.qemu-kvm来创建虚拟机 通过阅读man qemu-kvm手册而清楚的. 于20160430阅读 [root@kvm1 ~]# /usr/libexec/qemu-kvm ...