#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 111
int sg[111];
int get_sg(int s){ // 记忆化搜索
if(sg[s]!=-1) return sg[s]; // 不为-1,说明s的sg值已经被计算了,记忆化搜索不用再搜索计算了,直接返回已经算出来的结果
bool vis[MAXN]={0}; // 标记各个数是否被访问过,用于实现mex运算
for(int i=1; i<=s; ++i){ // 枚举取几个石子,转移到下一个局面
vis[get_sg(s-i)]=1; // 标记下一个局面s-i的sg值
}
for(int i=0; ; ++i){ // 找到最小的没有被标记的非负整数,就是mex运算的实现
if(!vis[i]){ // 没有被标记
return sg[s]=i; // 当前局面的s的sg值就等于最小的没有被标记的sg值
}
}
}
void get_sg(){ // 从小到大枚举,依次计算SG值
// 同上
for(int s=0; s<MAXN; ++s){
bool vis[MAXN]={0};
for(int i=1; i<=s; ++i){
vis[sg[s-i]]=1;
}
for(int i=0; ; ++i){
if(!vis[i]){
sg[s]=i;
break;
}
}
}
}
int main(){
memset(sg,-1,sizeof(sg));
for(int i=0; i<MAXN; ++i){
printf("%d ",get_sg(i));
}
puts("\n");
get_sg();
for(int i=0; i<MAXN; ++i){
printf("%d ",get_sg(i));
}
return 0;
}
尼姆博弈的SG值计算简单模板
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.