SG(x) = 0,必败
SG(x) != 0,必胜
如果是多张图的话
石子堆数是10000,所以一共是10000个状态,枚举集合的个数是100
时间复杂度就是1e6
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 110, M = 10010; 4 int n, k; 5 int s[N], f[M]; 6 //s存储给出的各个数 7 //f存储每堆石子的sg的值 8 int sg(int x) { 9 if (f[x] != -1) { //如果已经被算过了,不继续计算了,直接返回 10 return f[x]; 11 } 12 unordered_set<int> S; //存储当前这个局面能到的所有局面 13 for (int i = 0; i < k; i++) { 14 int sum = s[i]; //现在sum[i]就是集合中的数,也就是可以取出的石子数 15 if (x >= sum) { 16 S.insert(sg(x - sum)); 17 } 18 } 19 for (int i = 0; ; i++) { //找到集合当中不存在的最小的自然数是多少 20 if (!S.count(i)) { 21 return f[x] = i; 22 } 23 } 24 } 25 int main() { 26 cin >> k; 27 for (int i = 0; i < k; i++) { 28 cin >> s[i]; 29 } 30 cin >> n; 31 memset(f, -1, sizeof f); //用记忆化搜索来做 32 int res = 0; 33 for (int i = 0; i < n; i++) { 34 int x; 35 cin >> x; 36 res ^= sg(x); 37 } 38 if (res) { 39 cout << "Yes" << endl; 40 } else { 41 cout << "No" << endl; 42 } 43 return 0; 44 }