题意:给定n个集合,询问能够组成一种特定集合所能选的最大个数
无脑状压,循环顺序无所谓,T_T其实更习惯状态在前,序号在后
代表对于当前的状态是否能够由此时的集合转移得到(时间似乎变长了~~Orz)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e3+10;
int ill[N],f[(1<<15)+10],cnt[(1<<15)+10],n,d,K;
void pre()
{
for(int i=0;i<(1<<d);i++)
for(int j=1;j<=d;j++) if((1<<(j-1))&i)
cnt[i]++;
}
int main()
{
scanf("%d%d%d",&n,&d,&K);
pre();
for(int num,x,i=1;i<=n;i++)
{
scanf("%d",&num);
while(num--){scanf("%d",&x);ill[i]+=(1<<(x-1));}
}
for(int j=(1<<d)-1;j+1;j--)
for(int i=1;i<=n;i++)
/*或者
for(int i=1;i<=n;i++)
for(int j=(1<<d)-1;j+1;j--)
*/
f[j|ill[i]]=max(f[j|ill[i]],f[j]+1);
int ans=-1;
for(int i=0;i<(1<<d);i++)
if(cnt[i]==K)ans=max(ans,f[i]);
printf("%d\n",ans);
return 0;
}