你需要将 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);
}
}
浙公网安备 33010602011771号