HDU 4529

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

列一个计划,清明前做好状压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;
}

  

时间: 2024-10-25 21:25:56

HDU 4529的相关文章

HDU - 4529 郑厂长系列故事――N骑士问题 (状态压缩DP)

Description 郑厂长不是正厂长 也不是副厂长 他根本就不是厂长 还是那个腾讯公司的码农 一个业余时间喜欢下棋的码农 最近,郑厂长对八皇后问题很感兴趣,拿着国际象棋研究了好几天,终于研究透了.兴奋之余,坐在棋盘前的他又开始无聊了.无意间,他看见眼前的棋盘上只摆了八个皇后,感觉空荡荡的,恰好又发现身边还有几个骑士,于是,他想把这些骑士也摆到棋盘上去,当然棋盘上的一个位置只能放一个棋子.因为受八皇后问题的影响,他希望自己把这些骑士摆上去之后,也要满足每2个骑士之间不能相互攻击. 现在郑厂长想

hdu 4529 Double Dealing (置换群)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; __int64 gcd(__int64 a,__int64 b) { if(b==0) return a; return gcd(b,a%b); } int main() { int n,k,i,j,vis[810],m,num[810],x; __int64 res,cot; while(~scanf(

ACM总结——dp专辑(转)

感谢博主——      http://blog.csdn.net/cc_again?viewmode=list       ----------  Accagain  2014年5月15日 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. 本人动态规划博客地址:http://blog.csdn.net/cc_again/article/category/1261899 ***********************

【DP专辑】ACM动态规划总结

转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. 本人动态规划博客地址:http://blog.csdn.net/cc_again/article/category/1261899 ******************

(转)dp动态规划分类详解

dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. ****************************************************************************************** 动态规划(英语:Dynamic programm

这个是转的。学完就删_(:з」∠)_

原文链接:http://blog.csdn.net/cc_again/article/details/25866971 好多dp:http://blog.csdn.net/cc_again/article/category/1261899 一.简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见的.主要包括递推.背包.LIS(最长递增序列),LCS(最长公共子序列),下面针对这几种类型,推荐一下比较好的学习资料和题目. 1.递推: 递推一般形式比较单一,从前往后,

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

hdu 1269 (强联通分量Tarjan入门)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10075    Accepted Submission(s): 4529 Problem Description 为 了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单 向的,就是说若称某通道连通

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;