问题描述

BZOJ1688


题解

背包,在转移过程中使用状压。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') ch=getchar(),fh=-1;
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=17;

int n,d,k;
int opt[1<<17];
int dis[1007],tot;

int count(int x){
    int res=0;
    while(x){
        if(x&1) ++res;
        x>>=1;
    }
    return res;
}

int main(){
    read(n);read(d);read(k);
    for(int i=1,num,x;i<=n;i++){
        read(num);
        while(num--){
            read(x);
            dis[i]|=(1<<(x-1));tot|=(1<<(x-1));
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=(1<<d)-1;j>=0;j--){
            if(count(dis[i]|j)>k) continue;
            int pos=(dis[i]|j);
            opt[pos]=max(opt[pos],opt[j]+1);
            ans=max(ans,opt[pos]);
        }
    }
    printf("%d\n",ans);
    return 0;
}