细菌 状态压缩
1531: 细菌(disease)
时间限制: 1 Sec 内存限制: 64 MB提交: 17 解决: 9
[提交][状态][讨论版]
题目描述
近期,农场出现了D(1≤D≤15)种细菌。John要从他的N(1≤N≤1000)头奶牛中尽可能多地选些产奶,但是如果选中的奶牛携带了超过K(1≤K≤D)种不同细菌,所生产的奶就不合格。请你帮助John计算出最多可以选择多少头奶牛。
输入
第1行:三个整数N,D,K。
下面N行:第i行表示一头牛所携带的细菌情况。第一个整数di表示这头牛所携带的细菌种类数,后面di个整数表示这些细菌的各自种类标号。
输出
一个数M,最大可选奶牛数。
样例输入
6 3 2
0
1 1
1 2
1 3
2 2 1
2 2 1
样例输出
5
太机智了,用二进制压缩状态、(当然学的别人的了,好像之前做的树状数组的类型也有这回事)
#include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <iostream> #define ll long long using namespace std; int d,n,k,a[1005]; ll pow(ll x,ll n){ ll f=1; while(n){ if(n&1){ f*=x; } x*=x; n>>=1; } return f; } int work(int x){ int c=0; while(x){ if(x&1) c++; x>>=1; } return c; } int main(){ //freopen("data.in","r",stdin); int c,t; scanf("%d%d%d",&n,&d,&k); for(int i=0;i<n;i++){ scanf("%d",&c); while(c--){ scanf("%d",&t); a[i]+=pow(2,t-1); } } int mx=0,cn; for(int i=0;i<pow(2,d);i++){ cn=0; if(work(i)>k)continue; for(int j=0;j<n;j++){ if((i|a[j])==i) cn++; } mx=max(cn,mx); } printf("%d\n",mx); }