尼姆博弈的SG值計算簡單模板

#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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章