zoukankan      html  css  js  c++  java
  • 模板

    1.要从必胜或必败的局面反推

    2.SG函数

    只要当前状态可以转移到的状态中有一个是败态,那么当前状态就是胜态。胜态为N。

    如果当前状态可以转移到的所有状态都是胜态,那么当前状态就是败态。败态为P。

    sg函数为每个状态赋一个自然数的值,这个值为除这个状态的后继外最小自然数。首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

    从图的汇点开始反推,可知汇点(第一个败态)的sg值为0。

    性质:

    败态等价于sg值为0。

    游戏和的SG函数等于各个游戏SG函数的Nim和。这样就可以将每一个子游戏分而治之,从而简化了问题。

    类似这样用

    ```cpp

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;

    const int MAXN=1000005;
    const int N=1000005;

    //f[N]:可改变当前状态的方式,N为方式的种类,f[N]要在getSG之前先预处理
    //SG[]:0~n的SG函数值
    //S[]:为x后继状态的集合
    vector<int> nextofSG[MAXN];
    int f[N],SG[MAXN],S[MAXN];
    void getSG(int n){
    for(int i = 1; i <= n; i++){
    int l=nextofSG[i].size();
    //后继状态 最多有l 种
    for(int j=0;j<=l;j++){
    S[j]=0;
    }
    for(auto vi:nextofSG[i]){
    //vi:从i状态能取走的石子数
    S[SG[i-vi]]=1;
    }
    for(int j=0;j<=l;j++){
    if(!S[j]){
    SG[i] = j;
    break;
    }
    }
    cout<<"SG["<<i<<"]="<<SG[i]<<endl;
    }
    }

    int NNN=100;

    void enque(int id){
    int B=4;
    int cur=1;
    while(id+cur<=NNN){
    nextofSG[id+cur].push_back(id);
    cur*=B;
    if(B==1)
    break;
    }
    }

    int main() {
    #ifdef Yinku
    freopen("Yinku.in", "r", stdin);
    #endif // Yinku
    /*while(~scanf("%d%d",&b,&n)){
    if(n==1||ispow(n,b))
    fi();
    else{

    }
    }*/
    for(int i=0;i<=NNN;++i){
    enque(i);
    }
    getSG(NNN);
    }

    ```

  • 相关阅读:
    利用XAF中的FeatureCenter例子的,直接打开DetailView
    XAF 应用程序模型基础[转]
    XAF 如何给記錄增加版本控制?
    Simpler way to Create a Custom User Control
    建议将小川同志免费租借给欧洲用30年[转]文/端宏斌
    第六集 MSF构思阶段项目团队的组建
    MS_HotFix
    C#域内远程机文件信息注册表访问。
    访问 远程机 盘符 设置
    Silk_ 运行时_控件_属性_捕捉.
  • 原文地址:https://www.cnblogs.com/Yinku/p/10328425.html
Copyright © 2011-2022 走看看