码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1143 Number Game 状态压缩dp

时间:2015-05-06 23:08:40      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:dp   状态压缩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 100000000
using 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

标签:dp   状态压缩dp   

原文地址:http://blog.csdn.net/qq_24667639/article/details/45539995

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!