POJ 1143 Number Game 状态压缩dp

#include <cstdio>#include <iostream>#include <algorithm>#include <queue>#include <stack>#include <cstdlib>#include <cmath>#include <set>#include <map>#include <vector>#include <cstring>#define INF 100000000using namespace std;int ans[30];int a[30];int d[(1<<20)+10];int fun(int dp){if(dp == 0){return d[0] = 0;}if(d[dp] != -1) {return d[dp];}d[dp] = 0;for(int i = 2; i <= 20;i++){int state = dp;if(state & (1 << (i-1))){for(int j = 2;j <= 20;j++){if(!(state&(1 <<(j-1)))){for(int k = 1;k * i <= 20;k++){for(int w = 1;k * i + w * j <= 20;w++ ){int q = k * i + w *j;if(state&(1 << (q-1))){state ^= (1 <<(q-1));}}}}}int k = i;while(k <= 20){if(state&(1 << (k-1))){state ^= (1 <<(k-1));}k+=i;}d[dp] |= !fun(state);}}return d[dp];}int main(){int n;int q = 1;memset(d,-1,sizeof(d));while(scanf("%d",&n),n){int dp = 0;for(int i = 0;i < n;i++){scanf("%d",&a[i]);dp ^= (1 << (a[i]-1));}memset(ans,0,sizeof(ans));for(int i = 0;i < n;i++){int state = dp;//寻找他对手的可能的状态for(int j = 2;j <= 20;j++){if(!(state&(1 <<(j-1)))){for(int k = 1;k * a[i] <= 20;k++){for(int w = 1;k * a[i] + w * j <= 20;w++ ){int g = k * a[i] + w *j;if(state&(1 << (g-1))){state ^= (1 <<(g-1));}}}}}int k = a[i];while(k <= 20){if(state&(1 << (k-1))){state ^= (1 <<(k-1));}k += a[i];}ans[a[i]] = !fun(state);//他的状态取决于他对手是否存在有一个必输态}queue<int> que;for(int i = 2;i <= 20;i++){if(ans[i] == 1){que.push(i);}}printf("Test Case #%d\n",q++);if(!que.empty()){cout << "The winning moves are:";while(!que.empty()){cout <<" "<< que.front();que.pop();}cout << endl;}else{cout << "There's no winning move." << endl;}cout << endl;}return 0;}

,而是自己。在你成功地把自己推销给别人之前,

POJ 1143 Number Game 状态压缩dp

相关文章:

你感兴趣的文章:

标签云: