poj 2436 Disease Management

//有 D(<=15) 种疾病在 N 头牛中,告知每头牛所患的病,问至多能选择多少头牛,使得它们所患的病总数不超过 K
//方法:枚举所有疾病种类(不大于 k),检查每头牛患的病是否落在该范围内,比较找出最大的数目
#include<iostream> //位运算
using namespace std;

int cow[1002]; //cow[]表示牛携带的疾病的值,若患有 i 种疾病,则第(i-1)位上的值是1 .假如患有第 1 和 5 种疾病,则表示为 10001=17
int main()

{
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
int i,j,di,a;
for(i=1;i<=n;++i)
{
scanf("%d",&di);
while(di--)
{
scanf("%d",&a);
a=1<<(a-1); //让a定位到cow[i]右起的第(a-1)位
cow[i] = cow[i] | a; //让cow[i]右起的第(a-1)位的值是1
}

}
int res=0;
for( i = 1 ;i < ( 1<<d ) ;++i) //枚举疾病种类,例如当i= 1011,表示所允许带的疾病种类为 1,2,4 枚举上界是(1<<d)-1 表示全部疾病:2^0+2^1+...+2^(d-1)=(2^d)-1
{

j=i;
int s=0;
while(j>0) //统计二进制i 所有位上出现 1 的次数s,即是疾病种类的总数
{

j-=(j&(-j)); //j&(-j)表示二进制j 右起第一个1,比如j=10100,则j&(-j)=100
s++;

}
if(s>k) //疾病种类必须不大于 k ,注意这里不能 break;
continue;

int num=0;
for(j=1;j<=n;++j) //逐一检查,若该cow所携带的疾病种类全部落在二进制 i 所表示的范围内,则可以milk
if( ( cow[j] | i ) == i ) //只要有出现 i 所表示 之外 的疾病种类,则 或 的值肯定不等于 i,即不能milk. 注意不要写成 if(cow[j]|i==i)
num++;

res=max(res,num);
}
printf("%d\n",res);
return 0;
}

posted on 2011-07-22 20:32  sysu_mjc  阅读(161)  评论(0编辑  收藏  举报

导航