您的位置:首页 > 其它

nyoj-167 找奶牛病毒 “按位或”运算 递归

2013-03-22 09:03 246 查看
小珂的工作
时间限制:1000 ms | 内存限制:65535 KB
难度:4“”
描述

小珂有一个奶牛场,奶牛场最近在流行D(1<D<=15)种病毒,小珂的农场一共有N(1<N<=1000)只奶牛,含超过K(1<=K<=D)种病毒的牛奶不得不丢弃.(牛奶中含有奶牛身上的病毒)。现在希望你写一个程序,来确定一下一个桶里的最多可以包含多少头奶牛的牛奶。

输入
第一行一个整数M(1<M<=7),表示有M组测试数据,接下来的M组数据的第一行有三个整数,N,D,K,分别表示奶牛的数量,病毒的总种类,最多一个桶中可以包含的病毒数量。接下来N行,第i行,第一个数 i1,表示第i头牛包含的病毒种类个数,随后i1个数,表示的是病毒种类的标号(默认对D个病毒尽心标号,从1到D ),如果i1 为0,表示第没有病毒。
输出
每组数据输出可以最多挤多少头牛(不换桶),换行结束。
样例输入

1
6 3 2
0
1 1
1 2
1 3
2 2 1
2 2 1

样例输出

5

解题思路:这个题的规律是找包含关系最大的数目。包含关系 用到位运算里面的 |(按位或)运算,当a面包含b这个数,a|b==a;就是如果包含的话,运算后a是不变的。这个题就是用到这个思想。另外就是递归,找出当选择K种病毒时,我们找出此时最多的数量就行。
代码:

View Code

#include<stdio.h>
#include<string.h>
int bit[20],cow[1001];
int max,n,d,k;
void dfs(int at,int num,int all)
{
//at第几种病毒 num是当前病毒总数 all已经选定的病毒
if(d-at+1<k-num)
return ;
if(num==k)
{
int ans=0,i;
for(i=0;i<n;++i)
{
if(cow[i]==(cow[i]&all))//看此时i牛的病是否被包含在已有病毒里面
ans++;
}
if(ans>max)
max=ans;
return;
}
dfs(at+1,num,all);//不选
dfs(at+1,num+1,all|=bit[at]);//选择
}

int main()
{
int i,j,x,T,m;
scanf("%d",&T);
for(i=0;i<16;++i)//初始bit数组
bit[i]=1<<i;
while(T--)
{
scanf("%d%d%d",&n,&d,&k);
memset(cow,0,sizeof(cow));
max=0;
for(i=0;i<n;++i)
{
scanf("%d",&m);
for(j=1;j<=m;++j)
{
scanf("%d",&x);
cow[i]|=bit[x];//加入此种牛
}
}
dfs(1,0,0);
printf("%d\n",max);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: