Hackers' Crackdown UVA11825

发布时间 2023-04-17 23:18:27作者: towboat

你需要将 n 个集合分成尽量多组,使得每一组里面所有集合的并集等于全集

 

 

3
2   1 2
2   0 2
2   0 1
4 1 1 1 0 1 3 1 2 0

 

 

 f[S]= max(f[S], f[S-j] +1 )

且 j是一个包含所有点的集合

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; 
const int N =20, M=(1<<16); 
 int n,a[N],b[M+3],f[M+3]; 
 
 void solve(int cas){
 	memset(a,0,sizeof a) ;
 	memset(b,0,sizeof b);
 	memset(f,0,sizeof f) ;
 	for(int i=0;i<n;i++){
 		int x,t; cin>>t;
 		a[i]=(1<<i); 
 		while(t--) cin>>x,a[i]|=(1<<x);
 	}
 	for(int S=0;S<(1<<n);S++){
 		b[S]=0;
 		for(int i=0;i<n;i++) 
 			if(S&(1<<i)) b[S]|=a[i] ; 
 	}
 	for(int S=0;S<(1<<n);S++){
 		f[S]=0;
	 	for(int j=S;j;j=(j-1)&S){
	 		if(b[j]==(1<<n)-1) f[S] =max(f[S],f[S-j]+1) ;
	 	}
 	} 
 	cout<<"Case "<<cas<<": "<<f[(1<<n)-1]<<endl;
 }
 signed main(){
 	int cas=0;
 	while(cin>>n&&n){
 		solve(++cas);
	 }
 
}