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

转载自: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. Codeforces Round #119 (Div. 2)

    A. Cut Ribbon \(f(i)\)表示长为\(i\)的布条最多可以剪几段. B. Counting Rhombi \(O(wh)\)枚举中心计算 C. Permutations 将序列一映射 ...

  2. jquery中对小数进行取整、四舍五入的方法

    再和大家分享一个对多位小数进行四舍五入的方法: <script language="javascript"> //对多位小数进行四舍五入 //num是要处理的数字 v为 ...

  3. Linux-同步异步非阻塞阻塞的解析

    一.理解同步.异步.阻塞.非阻塞 出场人物:老张,水壶两把(普通水壶,简称水壶:会响的水壶,简称响水壶). 1 老张把水壶放到火上,立等水开.(同步阻塞) 老张觉得自己有点傻. 2 老张把水壶放到火上 ...

  4. ID3算法 决策树的生成(1)

    # coding:utf-8 import matplotlib.pyplot as plt import numpy as np import pylab def createDataSet(): ...

  5. 利用zip(或者phar)协议进行本地文件包含

    $include_file=$_GET[include_file];if ( isset( $include_file ) && strtolower( substr( $includ ...

  6. unity中的欧拉角

    unity中欧拉角用的是heading - pitch -bank系统(zxy惯性空间旋转系统):当认为旋转顺序是zxy时,是相对于惯性坐标系旋转.当认为旋转顺序是yxz时,是相对于物体坐标系旋转. ...

  7. 【转】个人最常用的Eclipse快捷键

      记录下自己在Eclipse中最常使用的快捷键: 其实网上总结多的是,自己记录下自己平时最切身受益的一些快捷键. 1.SHIFT+ ALT+Z(刚学的): 条件:选中一段代码 会弹出上面的右键菜单, ...

  8. python escape sequences

    转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \' 单引号 \" 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 换行 \v 纵向制表符 \ ...

  9. Mac安装Appium

    通过淘宝镜像安装 npm --registry http://registry.cnpmjs.org install -g appium 如果提示权限不够的话,需要加sudo,并输入对应密码 sudo ...

  10. js中数组Array的一些常用方法总结

    var list = new Array()是我们在js中常常写到的代码,今天就总结一下Array的对象具有哪些方法. list[0] = 0; list[1] = 1; list[2] = 2; 或 ...