bzoj1688: [Usaco2005 Open]Disease Manangement 疾病管理 状压dp

来源:互联网 发布:格雷格.门罗数据 编辑:程序博客网 时间:2024/05/17 22:16

题意:给定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;}
阅读全文
0 0