集合-Nim游戏

与普通(NIM)游戏不同的地方是限制了每次拿东西的个数,这个个数会给定在集合(S)中,也就是说每次拿的数量只能在集合(S)中。

现在就可以把每一堆石子看成是一个有向图了,最主要就是用记忆化搜索来计算每一堆石子的(SG)函数,然后用定理判断即可。

#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <cstring>

using namespace std;

const int N = 110, M = 10010;
int f[M], s[N];
int n, m;

int sg(int x) {
    if (f[x] != -1) return f[x];
    
    unordered_set<int> S;
    for (int i = 0; i < n; i++) {
        int t = s[i];
        if (x >= t) S.insert(sg(x - t)); 
    }
    
    for (int i = 0; ;i++) {
        if (!S.count(i)) return f[x] = i;
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> s[i];
    cin >> m;
    
    memset(f, -1, sizeof f);
    int res = 0;
    for (int i = 0; i < m; i++) {
        int x; cin >> x;
        res ^= sg(x);
    }
    
    puts(res == 0 ? "No" : "Yes");
    
    return 0;
}
原文地址:https://www.cnblogs.com/ZhengLijie/p/15036291.html