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
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.
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.
Recommend
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); } }