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

    ```

  • 相关阅读:
    解决Xcode升级7.0后,部分.a静态库在iOS9.0的模拟器上,link失败的问题
    2014年工作总结
    工作还是事业
    海豚社区阶段性开发总结
    Xcode开发和调试总结
    iOS证书深究
    何为分类,UIImageView举例
    UIWebView的探索
    SugarSync网盘之NSDateFormatter
    ASP.NET程序从IIS6移植到IIS7时出现500.22错误(转)
  • 原文地址:https://www.cnblogs.com/Yinku/p/10328425.html
Copyright © 2011-2022 走看看