先,定义一下 状态Position P 先手必败 N x先手必胜

操作方法: 反向转移

相同状态 不同位置 的一对 相当于无

对于ICG游戏,我们可以将游戏中每一个可能发生的局面表示为一个点。并且若存在局面i和局面j,且j是i的后继局面(即局面i可以转化为局面j),我们用一条有向边,从i出发到j,连接表示局面i和局面j的点。则整个游戏可以表示成为一个有向无环图:

根据ICG游戏的定义我们知道,任意一个无法继续进行下去的局面为终结局面,即P局面(先手必败)。在上图中我们可以标记所有出度为0的点为P点。接着根据ICG游戏的两条性质,我们可以逆推出所有点为P局面还是N局面:

对于一个游戏可能发生的局面x,我们如下定义它的sg值:
(1)若当前局面x为终结局面,则sg值为0。
(2)若当前局面x非终结局面,其sg值为:sg(x) = mex{sg(y) | y是x的后继局面}。
mex{a[i]}表示a中未出现的最小非负整数。举个例子来说:
mex{0, 1, 2} = 3, mex{1, 2}=0, mex{0,1,3}=2

我们将上图用sg函数表示后,得到:

可以发现,若一个局面x为P局面,则有sg(x)=0;否则sg(x)>0。同样sg值也满足N、P之间的转换关系:
若一个局面x,其sg(x)>0,则一定存在一个后续局面y,sg(y)=0。
若一个局面x,其sg(x)=0,则x的所有后续局面y,sg(y)>0。

由上面的推论,我们可以知道用N、P-Position可以描述的游戏用sg同样可以描述。并且在sg函数中还有一个非常好用的定理,叫做sg定理:
对于多个单一游戏,X=x[1..n],每一次我们只能改变其中一个单一游戏的局面。则其总局面的sg值等于这些单一游戏的sg值异或和。

先定义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()计算

  1. //f[]:可以取走的石子个数
  2. //sg[]:0~n的SG函数值
  3. //hash[]:mex{}
  4. int f[N],sg[N],hash[N];
  5. void getSG(int n)
  6. {
  7. int i,j;
  8. memset(sg,,sizeof(sg));
  9. for(i=;i<=n;i++)
  10. {
  11. memset(hash,,sizeof(hash));
  12. for(j=;f[j]<=i;j++)
  13. hash[sg[i-f[j]]]=;
  14. for(j=;j<=n;j++) //求mes{}中未出现的最小的非负整数
  15. {
  16. if(hash[j]==)
  17. {
  18. sg[i]=j;
  19. break;
  20. }
  21. }
  22. }
  23. }

SG打表

  1. //注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
  2. //n是集合s的大小 S[i]是定义的特殊取法规则的数组
  3. int s[],sg[],n;
  4. int SG_dfs(int x)
  5. {
  6. int i;
  7. if(sg[x]!=-)
  8. return sg[x];
  9. bool vis[];
  10. memset(vis,,sizeof(vis));
  11. for(i=;i<n;i++)
  12. {
  13. if(x>=s[i])
  14. {
  15. SG_dfs(x-s[i]);
  16. vis[sg[x-s[i]]]=;
  17. }
  18. }
  19. int e;
  20. for(i=;;i++)
  21. if(!vis[i])
  22. {
  23. e=i;
  24. break;
  25. }
  26. return sg[x]=e;
  27. }

dfs

注意在SG表的初始化中,不用每次都初始;否则会T的,因为可以循环利用,这是一个强大的地方

HDU1536 实战

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<string.h>
  4. using namespace std;
  5. int s[],sg[],n;
  6. char op[];
  7. int SG_dfs(int x)
  8. {
  9. int i;
  10. if(sg[x]!=-)
  11. return sg[x];
  12. bool vis[];
  13. memset(vis,,sizeof(vis));
  14. for(i=;i<n;i++)
  15. {
  16. if(x>=s[i])
  17. {
  18. SG_dfs(x-s[i]);
  19. vis[sg[x-s[i]]]=;
  20. }
  21. }
  22. int e;
  23. for(i=;;i++)
  24. if(!vis[i])
  25. {
  26. e=i;
  27. break;
  28. }
  29. return sg[x]=e;
  30. }
  31. int main()
  32. {
  33. int k;
  34. while(scanf("%d",&n)!=EOF)
  35. {
  36. if(n==)
  37. break;
  38. for(int i= ; i<n ; i++)
  39. scanf("%d",&s[i]);
  40. sort(s,s+n);
  41. int m,cnt=;
  42. scanf("%d",&m);
  43. memset(sg,-,sizeof(sg));
  44. for(int i= ; i<m ; i++)
  45. {
  46.  
  47. scanf("%d",&k);
  48. int x=;
  49. while(k--)
  50. {
  51. int w;
  52. scanf("%d",&w);
  53. x^=SG_dfs(w);
  54.  
  55. }
  56. if(x!=)
  57. printf("W");
  58. else
  59. printf("L");
  60. }
  61. puts("");
  62. }
  63.  
  64. return ;
  65. }

什么是SG?+SG模板的更多相关文章

  1. SG函数模板(转)

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

  2. hdu 1536 SG函数模板题

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

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

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

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

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

  5. SG函数模板

    这篇虽然是转载的,但代码和原文还是有出入,我认为我的代码更好些. 转载自:http://www.cnblogs.com/frog112111/p/3199780.html 最新sg模板: //MAXN ...

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

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

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

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

  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. 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 ...

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

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

随机推荐

  1. Sqlite表结构读取工具,word批量转html,在线云剪贴板,文件批量提取工具;

    工欲善其事必先利其器,本周为您推荐工具排行 Sqlite表结构读取工具,word批量转html,在线云剪贴板,文件批量提取工具:     本周我们又要发干货了,准备好接受了吗? 为什么是干货,就是因为 ...

  2. ACM学习历程—HDU 3915 Game(Nim博弈 && xor高斯消元)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所 ...

  3. oracle隐含参数的查看与修改

    v$parameter视图中查询参数的时候其实都是通过x$ksppi和x$ksppcv这两个内部视图中得到的. 1.   可以通过如下方式查询当前实例的所有隐含参数: col name for a30 ...

  4. BZOJ1150:[CTSC2007]数据备份

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...

  5. java中toString() 、(String)、String.valueOf的区别

    1.采用toString() 在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常.采用这种方法时,通常派生类会覆盖Object里的toStrin ...

  6. 滑动swipe的妙用

    转自:http://www.cnblogs.com/NEOCSL/archive/2013/03/04/2942861.html iterface ITouchable; function OnPic ...

  7. JavaScript设模式---单例模式

    单例模式也称为单体模式,其中: 1,单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量. 逻辑单元中的代码通过单一的变量进行访问. 2,三个特点: ① 该类只有一个实例: ...

  8. 【原】spring jar 下载

    作者:david_zhang@sh [转载时请以超链接形式标明文章] 链接:http://www.cnblogs.com/david-zhang-index/p/8098965.html 1.进入官网 ...

  9. tomcat solr 限制ip

    <Context path="/solr" reloadable="false" docBase="/var/www"> < ...

  10. LAMP 1.4 PHP编译安装问题解决

    环境:centos X64 最小化安装 php版本:php-5.4.3 安装前.先安装些软件和库文件 yum install -y gcc gcc-c++ make zlib zlib-devel p ...