版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Description
Cici手下有N个小KID(1<=N<=1000),每个小KID都有若干种特异功能,这些功能从1开始编号,其总数不超过15 ,如
果小KID们所有的特异功能总类别数超过K的话,Cici管不住他们了。现在Cici当然不想让他们翻天覆地,所以只能
从N个小KID中选择一部分出来,他希望选的小KID的人数越多越好。
Input
第一行输入N,D,K
下面N行,用于描述这N个小KID的情况,格式如下:
先给出当前这个小KID所有的特异功能,然后再给些它们的编号分别是多少.
Output
如题
Sample Input
6 3 2
0
1 1
1 2
1 3
2 2 1
2 2 1
Sample Output
5
//Cici可以选择1, 2, 3, 5, 6这五个小KID,他们所拥有的特异功能总类数为2种,即第一种和第二种,没有超过K。
HINT
这道题的特异功能数量可以用二进制来表示,例如这个样例:
KID的序号 | 拥有的特异功能 |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 2、1 |
5 | 2、1 |
其实这个样例每一个都可以化为二进制:
第一个:001
第二个:010
第三个:100
第四个:011
第五个:011
再一个个枚举,要让特异功能数量尽量等于K,那么就可以进行或运算,若或运算后,得出来的结果与原值相等,就加入这个KID。最终加出来的结果比之前最大值大,则替换最大值。
#include <bits/stdc++.h>
using namespace std;
int n,d,k,a[1001],s=0;
int two[17]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
//two用来表示2的幂次方
void dfs(int dep,int pre,int sum)
{
if(dep==k)
{
int ans=0;
for(int i=1;i<=n;i++)
{
if((a[i]|sum)==sum)
{
ans++;
}
}
s=max(ans,s);
return ;
}
for(int i=pre+1;i<=d;i++)
{
dfs(dep+1,i,sum+two[i]);
}
}
int main(){
cin>>n>>d>>k;
for(int i=1;i<=n;i++)
{
int m,x;
cin>>m;
for(int j=1;j<=m;j++)
{
cin>>x;
a[i]+=two[x];
}
}
dfs(0,0,0);
cout<<s<<endl;
return 0;
}