hdu3185 Dead Or Alive

Dead Or Alive

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 69    Accepted Submission(s): 6


Problem Description
Only several people survive after Doomsday, and a small number of cities have not been destroyed. yifenfei wants to arrange these people to live on the available cities.
Now all the people follow yifenfei to pass the cities.
But there are some restrictions on the cities. Some people will die when pass some cities and every city has a population limitation. If people can’t find a city to live after passing all cities they will be dead! So the order of passing the cities is important.
 

Input
The first line an integer T (1<=T<=100) which means the number of test cases.
Each case starts with two integers n and m, which means the number of people and the number of cities. (1<= n <= 31, 1 <= m <= 10)
Second line has m integers, the ith integer Ci means ith city’s population limitation. The cities are ordered from 0 to m-1. (1 <= Ci <= 6)
Then n lines follow. Each line starts with an integer k which means the number of cities this people will die when passing it. Then k integers follow.
 

Output
The maximum number of people can survive!
 

Sample Input
 
  
23 33 3 21 102 1 23 32 1 22 0 12 0 21 2
 
Sample Output
 
  
32
 

Source
 

Recommend

lcy   |   We have carefully selected several similar problems for you:   3190  3187  3184  3186  3188 


Solution: I don't know why there are only four people who have been there before (one of them submitted 2 times), and it was still 7 years ago.

My algorithm may not be the correct solution to this question, it ran for more than 7700 milliseconds, and the other 4 people only ran for more than 200 milliseconds at most.

We first enumerate the order of all cities (search them out), there are !m kinds. First use a binary system to record who will die in each city (use 01 to represent the record), record it as g[i], when searching, we use a binary system to record which cities must be placed in front of this city (If it passes through, it will die), 0 means it must be placed in the front, 1 means not necessarily.

Then the transfer is now=la&(~g[i]) (binary operation) //la is the placement requirement of the previous position, and now is the placement requirement of this position.

Take the minimum value at the end


Code (in the clouds and mists mentioned earlier):

#include<bits/stdc++.h>
using namespace std;
int ans,n,m,gg[50],a[50],b[50],c[50];
long long g[50];
void dfs(int x,long long la,int k,int k1,int sum){
	long long now;
	int t1, kk;
	if(x>m){
		if(m-sum-k>0)k+=m-sum-k;
		years=min(years,k);
		return;
	}	
	for(int i=0;i<m;i++)
	 if(gg[i]==0){
	 	gg[i]=1;b[x]=i;
		now=la&(~g[i]);
		c[x]=now;
	 	t1=k1-__builtin_popcount(now);
	 	//printf("%d %d\n",i,t1);
	 	//k1: the number of 1s in now
		//t1: The number of differences between now and 1 in la
	 	if(n-k1+t1-k>sum){
	 		kk=n-k1+t1-k-sum;
	 		dfs(x+1,now,k+kk,k1-t1,sum+a[i]);
		 }
		  else
	 	dfs(x+1,now,k,k1-t1,sum+a[i]);
	 	gg[i]=0;
	 }
}
int main(){
	int t1,i,j,k1,t;
	scanf("%d",&t1);
	while(t1--){
		memset(gg,0,sizeof(gg));
		memset(g,0,sizeof(g));
		scanf("%d%d",&n,&m);
		years=n;
		for(i=0;i<m;i++){
			scanf("%d",&a[i]);
		}
		for(i=1;i<=n;i++){
			scanf("%d",&k1);
			for(j=1;j<=k1;j++){
				scanf("%d",&t);
				g[t]|=1<<(i-1);
			}
		}
		dfs(1,(1<<n)-1,0,n,0);
		printf("%d\n",n-ans);
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324892163&siteId=291194637