您的位置:首页 > 其它

Codeforces 768E Game of Stones

2017-02-22 15:36 459 查看
NIM游戏改编,每堆石头同一种操作不能超过两次。

可以用SG[i][2^i-1]推出所有状态,复杂度是O(n*n*2^n)。

所以用记忆化搜索,当第一维状态为num时,第二维2^(num-1)前的所有1都可以去掉,因为那些点不会再被取到了。

代码:

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

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<int, ll> PIL;
typedef pair<string, string> PSS;

const int N = 65;
map<PIL, int> SG;
map<PIL, bool> found;
int grundy
;

int dfs(int num, ll sc, int ml) {
for(int i = num; i <= ml; i++) {
if(sc&(1LL<<i)) sc ^= (1LL<<i);
}
if(found[{num, sc}]) return SG[{num, sc}];

bool vis
;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= num; i++) {
if(sc&(1LL<<(i-1))) vis[dfs(num-i, sc^(1LL<<(i-1)), num)] = 1;
}

int ret;
for(int i = 0; ; i++) {
if(!vis[i]) {
SG[{num, sc}] = ret = i;
found[{num, sc}] = 1;
break;
}
}
return ret;
}

void ini() {
SG[{0,0}] = 0;
found[{0,0}] = 1;
for(int i = 0; i <= 60; i++) {
grundy[i] = dfs(i, (1LL<<i)-1LL, 60);
}
}

int main() {
ini();
int n, nim = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
int t; scanf("%d", &t);
nim ^= grundy[t];
}
if(!nim) puts("YES");
else puts("NO");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: