4月补题

状压DPhdu6006


#include<iostream>
#include<cstring>
using namespace std;
int h[1<<10][1<<10];
int t,n,m,c[11],d[11],a[11][3],b[11][2],vis[11][101],ans;
void dfs(int now,int pro,int eng){
	if(now==n)
	 {
	 	return;
	 }
	 if(h[pro][eng]+n-now<=ans) 	 	return;	 
	 for(int i=0;i<(1<<m);i++){
	 	if(i&eng) {
	 		continue;	//这个eng考虑过了 
		 }
		int cnt=0;
	 	for(int j=0;j<m;j++){
	 		int temp=0;
		
	 		if(i&(1<<j)){ 
	 		
	 			for(int k=0;k<d[j];k++){
	 				int temp=b[j][k];
				//	 printf("%d %d %d %d %d
",i,j,temp,cnt,vis[now][temp]);
	 				if(vis[now][temp]==1){
	 					vis[now][temp]=2;
	 					cnt++;
						
					 }
				 }
			 }
		 }
		 
		 if(cnt==c[now]){
		 	
		 	h[pro|(1<<now)][eng|i]=h[pro][eng]+1;
		 	ans=max(ans,h[pro|(1<<now)][eng|i]);
		 	dfs(now+1,pro|(1<<now),eng|i);
		 }
		 for(int j=0;j<m;j++){
	 		if(i&(1<<j)){
	 			for(int k=0;k<d[j];k++){
	 				int temp=b[j][k];
	 				if(vis[now][temp]==2){
	 					vis[now][temp]=1;
					 }
				 }
			 }
		 }
	 }
	 ans=max(ans,h[pro][eng]);
	 dfs(now+1,pro,eng);
}
int main(){
	scanf("%d",&t);
	int T=0;
	while(t--){
		ans=0;
		memset(h,-1,sizeof(h));
		h[0][0]=0;
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++){
			scanf("%d",&c[i]);
			for(int j=0;j<c[i];j++){
				scanf("%d",&a[i][j]);
				vis[i][a[i][j]]=1;
			}
		}
		for(int i=0;i<m;i++){
			scanf("%d",&d[i]);
			for(int j=0;j<d[i];j++){
				scanf("%d",&b[i][j]);
			}
		}
		dfs(0,0,0);
		printf("Case #%d: %d
",++T,ans);
	}	
	return 0;
} 
原文地址:https://www.cnblogs.com/Crazycatmiao/p/6742837.html