你需要将 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); } }
标签:Hackers,cas,UVA11825,Crackdown,集合,include From: https://www.cnblogs.com/towboa/p/17327937.html