模板 - 数学 - 博弈论 - SG函数

f[i]表示状态i的后继状态,把它的后继状态push_back()进去,然后调用getSG()就可以得到SG函数。无法转移的状态都是失败状态,这种写法貌似只能向标号更小的状态转移(本身这个图就是DAG,就有拓扑序,所以本质上无所谓,更何况取石子非常直观),所以一般f[0]就是失败状态。当然也可能会有别的失败状态。

多个公平组合游戏的和,只需要把他们分别的SG函数求出来然后求个异或和即可。

vector<int> f[1005];

int SG[1005], S[1005];
int getSG() {
    for(int i = 0; i <= n; ++i)
        SG[i] = 0;
    for(int i = 1; i <= n; i++) {
        int l = f[i].size();
        for(int j = 0; j <= l; j++)
            S[j] = 0;
        for(auto &j : f[i])
            S[SG[j]] = 1;
        for(int j = 0; j <= l; j++) {
            if(!S[j]) {
                SG[i] = j;
                break;
            }
        }
    }
    return SG[n];
}
posted @ 2020-02-12 02:50  KisekiPurin2019  阅读(109)  评论(0编辑  收藏  举报