sg函数入门理解

Posted warmingtxdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sg函数入门理解相关的知识,希望对你有一定的参考价值。

首先理解sg函数必须先理解mex函数

mex是求除它集合内的最小大于等于0的整数,例:mex1,2=0;mex2=0;mex0,1,2=3;mex0,5=1。

而sg函数是啥呢?

对于任意状态 x , 定义 sg(x) = mex(f),其中f 是 x 后继状态的sg函数值的集合(就是上述mex中的数值)。最后返回值(也就是sg(x))为0为必败点,不为零必胜点。

技术图片

看不懂,咱直接来个例子:

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

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

 

x=1时,可以取走1-f1个石子,剩余0个,mexsg[0]=0,故sg[1]=1;

x=2时,可以取走2-f1个石子,剩余1个,mexsg[1]=1,故sg[2]=0;

x=3时,可以取走3-f1,3个石子,剩余2,0个,mexsg[2],sg[0]=0,0,故sg[3]=1;

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

x=5时,可以取走5-f1,3,4个石子,剩余4,2,1个,mexsg[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]表示可以有多少种走法)

这下就ojbk了吧

技术图片

f[]需要从小到大排序

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

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

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

再附个模板吧

 1 //f[]:可以取走的石子个数
 2 //sg[]:0~n的SG函数值
 3 int f[maxn],sg[maxn],mex[maxn];
 4 void getSG(int n)
 5     int i,j;
 6     memset(sg,0,sizeof(sg));
 7     for(i=1;i<=n;i++)
 8         memset(mex,0,sizeof(mex));
 9         for(j=1;f[j]<=i&&f[j]<=m;j++) //注意加f[i]的限定条件,此处为f[j]<=m
10             mex[sg[i-f[j]]]=1;
11         for(j=0;j<=n;j++)    //求mex中未出现的最小的非负整数
12             if(mex[j]==0)
13                 sg[i]=j;
14                 break;
15             
16         
17         //cout<<i<<" "<<sg[i]<<endl;
18     
19 

 

以上是关于sg函数入门理解的主要内容,如果未能解决你的问题,请参考以下文章

SG函数入门

博弈论初步(SG函数)

关于sg函数的一些证明

博弈论进阶之SG函数

SG函数

博弈论题目总结——SG组合游戏及变形