#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值計算簡單模板
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.