推荐几篇文章:https://blog.csdn.net/strangedbly/article/details/51137432(SG函数详细介绍)
https://blog.csdn.net/shahdza/article/details/7832997 博弈题集
SG函数解题模型:
1.把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或。
即sg(G)=sg(G1)^sg(G2)^...^sg(Gn)。
2.分别考虑没一个子游戏,计算其SG值。
SG值的计算方法:(重点)
A.可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);
B.可选步数为任意步,SG(x) = x;
C.可选步数为一系列不连续的数,用模板计算。
模板:假设起点为n,总共有m种移动步数可以选择
1.打表(首选打表预处理)
思路:对于一个位置,找到其所有的后继点的SG值有哪些,该位置的SG值即为不等于其后继点的SG值的最小非负整数
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1005; 6 const int maxm=105; 7 int f[maxm],sg[maxn]; //f表示移动步数,sg表示每个位置的sg值 8 bool vis[maxn]; //vis表示对于某个位置来说,其后继节点的sg值有哪些 9 int n,m; 10 11 void get_sg() 12 { 13 int i,j; 14 memset(sg,0,sizeof(sg)); 15 for ( i=1;i<=n;i++ ) { 16 memset(vis,false,sizeof(vis)); 17 for ( j=1;f[j]<=i&&j<=m;j++ ) vis[sg[i-f[j]]]=true; //对后继节点所处的位置标记为true 18 for ( j=0;j<=i;j++ ) { //该位置的sg值 19 if ( !vis[j] ) { 20 sg[i]=j; 21 break; 22 } 23 } 24 } 25 }