细菌 状态压缩

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
",mx);
}
原文地址:https://www.cnblogs.com/acmtime/p/5721649.html