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

HDU 4529

时间:2015-03-30 22:56:56      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

好题。果然好题,经典了。

列一个计划,清明前做好状压DP。之后就刷剩下的MULTI。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int Status=(1<<8);

int dp[2][11][Status][Status];  	//滚动数组实现。dp[i][j][k][l],其中表示当前状态i(权且认为是i行),推出下一个状态next,i状态以前总共使用了
				//j个骑士,ki-1行放骑士的状态,l是i行的状态,这时的放置方法数。答案DP就行。 
bool crashpt[Status][Status];	//当前行状态与上两行的状态是否有不相容 
bool crashpo[Status][Status];	//当前行(要推出的行)与上一行状是否有冲突 
int total[Status];		//每种状态会用了多少个骑士。 
int G[10],n;	//G[i]表示第i行可放骑士的位置的情况,压 缩。 
char str[10];

void predo(){
	memset(crashpt,false,sizeof(crashpt));
	memset(crashpo,false,sizeof(crashpo));
	memset(total,0,sizeof(total));
	for(int i=0;i<Status;i++){
		for(int j=0;j<8;j++){
			if(i&(1<<j)) total[i]++;
		}
		for(int j=0;j<Status;j++){
			if((j&(i>>2))||(i&(j>>2))) crashpo[i][j]=true;
			if((j&(i>>1))||(i&(j>>1))) crashpt[i][j]=true;
		}
	}
}

void slove(){
	int cur=0,next=1;
	memset(dp[0],0,sizeof(dp[0]));
	dp[cur][0][0][0]=1;
	for(int i=0;i<8;i++){
		for(int j=0;j<=n;j++){
			for(int t=0;t<Status;t++){
				for(int o=0;o<Status;o++){
					if(!dp[cur][j][t][o]) continue;
					for(int now=0;now<Status;now++){
						if(j+total[now]>n) continue;
						if((now&G[i+1])!=now) continue;
						if(crashpt[now][t]||crashpo[now][o]) continue;
						dp[next][j+total[now]][o][now]+=dp[cur][j][t][o];
					}
				}
			}
		}
		memset(dp[cur],0,sizeof(dp[cur]));
		swap(cur,next);
	}
	int ans=0;
	for(int i=0;i<Status;i++){
		for(int j=0;j<Status;j++)
		ans+=dp[cur][n][i][j];
	}
	printf("%d\n",ans);
}

int main(){
	int T;
	scanf("%d",&T);
	predo();
	while(T--){
		scanf("%d",&n);
		memset(G,0,sizeof(G));
		for(int i=1;i<=8;i++){
			scanf("%s",str);
			for(int j=0;j<8;j++){
				G[i]<<=1;
				if(str[j]==‘.‘) G[i]|=1;
			}
		}
		slove();
	}
	return 0;
}

  

HDU 4529

标签:

原文地址:http://www.cnblogs.com/jie-dcai/p/4379327.html

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