SG函数与SG定理

SG函数
\(mex\)运算:\(mex\)运算是一个施加于集合的运算,表示最小的不属于这个集合的非负整数。例如\(mex\{0,1,3\}=2,mex\{1\}=0,mex\{\}=0\)
\(SG\)函数:对于任意状态\(x\)\(SG(x)=mex(\{SG(y)|\)\(y\)\(x\)的后继状态\(\})\)
\(SG(x)==0\)\(x\)为必败态,\(SG(x)\neq 0\)\(x\)为必胜态
\(SG\)函数的计算可以使用动态规划或者记忆化搜索,设状态数的最大值为\(n\),转移数为\(m\),则时间复杂度\(O(n*m)\)

模板:动态规划计算\([0,n]\)的SG函数值

int SG[maxn],S[maxn],f[maxm];

void get_SG(int n,int m){
    int i,j;
    memset(SG,0,sizeof(SG));
    for(i=1;i<=n;i++){
        memset(S,0,sizeof(S));
        for(j=0;j<m && f[j]<=i;j++)
            S[SG[i-f[j]]]=1;  
        j=0;
        while(S[j]!=0) j++;
        SG[i]=j;
    }
}

相关题目:hdu1536 S-Nim
记忆化搜索计算\(SG\)函数,虽然每堆石子数最多为\(10000\),但是由于转移数最多为\(100\),所以\(SG\)函数的值不超过\(100\),可以开大小为\(110\)\(S\)数组

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define pi acos(-1.0)
#define lowbit(x) x&(-x)
using namespace std;

int number_s,s[110],T,number_a,a[110],SG[10010];

int f(int x){
    if(SG[x]!=-1) return SG[x];
    bool S[110];
    for(int i=0;i<=100;i++) S[i]=0;
    for(int i=1;i<=number_s && x-s[i]>=0;i++){
        S[f(x-s[i])]=1;
    }
    int i=0;
    while(S[i]) i++;
    return SG[x]=i;
}

int main(void){
    while(scanf("%d",&number_s)!=EOF && number_s){
        for(int i=1;i<=number_s;i++){
            scanf("%d",&s[i]);
        }
        sort(s+1,s+1+number_s);
        scanf("%d",&T);
        memset(SG,-1,sizeof(SG));
        SG[0]=0;
        while(T--){
            scanf("%d",&number_a);
            int ans=0;
            for(int i=1;i<=number_a;i++){
                scanf("%d",&a[i]);
                ans^=f(a[i]);
            }
            if(ans) printf("W");
            else printf("L");
        }
        printf("\n");
    }
    return 0;
}

SG定理
\(SG\)定理:游戏和的\(SG\)函数等于各个游戏的\(SG\)函数的异或和
\(SG\)函数表示除了后继状态\(SG\)函数值以外的最小值,也就是从\(SG(x)=k\)的状态可以转移到\(0,1,\cdots,k-1\)的所有状态。这和\(NIM\)博弈相同,所以可以通过异或和判断胜败。

posted @ 2020-07-30 17:03  fxq1304  阅读(198)  评论(0编辑  收藏  举报