SG函数模板
这篇虽然是转载的,但代码和原文还是有出入,我认为我的代码更好些。
转载自: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函数模板的更多相关文章
- hdu1536&&hdu3023  SG函数模板及其运用
		S-Nim Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit Status ... 
- SG函数模板(转)
		ps:sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3.me ... 
- hdu 1536 SG函数模板题
		S-Nim Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ... 
- 【非原创】sg函数模板
		学习博客:戳这里 解题模型: 1.把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或. 即sg(G)=sg(G1)^sg(G2)^...^sg(Gn) ... 
- 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 ... 
- HDU 1847-Good Luck in CET-4 Everybody!-博弈SG函数模板
		Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ... 
- hdu 1536 S-Nim(sg函数模板)
		转载自:http://blog.csdn.net/sr_19930829/article/details/23446173 解题思路: 这个题折腾了两三天,参考了两个模板,在这之间折腾过来折腾过去,终 ... 
- SG函数 模板
		int get_SG(int x) { ) return SG[x]; ]={}; ;i<=n;i++) ) v[get_SG(x-s[i])]=; int i; ;v[i];i++); SG[ ... 
- SG函数模板(洛谷2197nim游戏
		#include <iostream> #include <cstdio> #include <queue> #include <algorithm> ... 
随机推荐
- Codeforces Round #119 (Div. 2)
			A. Cut Ribbon \(f(i)\)表示长为\(i\)的布条最多可以剪几段. B. Counting Rhombi \(O(wh)\)枚举中心计算 C. Permutations 将序列一映射 ... 
- jquery中对小数进行取整、四舍五入的方法
			再和大家分享一个对多位小数进行四舍五入的方法: <script language="javascript"> //对多位小数进行四舍五入 //num是要处理的数字 v为 ... 
- Linux-同步异步非阻塞阻塞的解析
			一.理解同步.异步.阻塞.非阻塞 出场人物:老张,水壶两把(普通水壶,简称水壶:会响的水壶,简称响水壶). 1 老张把水壶放到火上,立等水开.(同步阻塞) 老张觉得自己有点傻. 2 老张把水壶放到火上 ... 
- ID3算法 决策树的生成(1)
			# coding:utf-8 import matplotlib.pyplot as plt import numpy as np import pylab def createDataSet(): ... 
- 利用zip(或者phar)协议进行本地文件包含
			$include_file=$_GET[include_file];if ( isset( $include_file ) && strtolower( substr( $includ ... 
- unity中的欧拉角
			unity中欧拉角用的是heading - pitch -bank系统(zxy惯性空间旋转系统):当认为旋转顺序是zxy时,是相对于惯性坐标系旋转.当认为旋转顺序是yxz时,是相对于物体坐标系旋转. ... 
- 【转】个人最常用的Eclipse快捷键
			记录下自己在Eclipse中最常使用的快捷键: 其实网上总结多的是,自己记录下自己平时最切身受益的一些快捷键. 1.SHIFT+ ALT+Z(刚学的): 条件:选中一段代码 会弹出上面的右键菜单, ... 
- python escape sequences
			转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \' 单引号 \" 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 换行 \v 纵向制表符 \ ... 
- Mac安装Appium
			通过淘宝镜像安装 npm --registry http://registry.cnpmjs.org install -g appium 如果提示权限不够的话,需要加sudo,并输入对应密码 sudo ... 
- js中数组Array的一些常用方法总结
			var list = new Array()是我们在js中常常写到的代码,今天就总结一下Array的对象具有哪些方法. list[0] = 0; list[1] = 1; list[2] = 2; 或 ... 
