Disease Manangement

Q - 枚举子集

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

 

Description

Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) is running through the farm. Farmer John would like to milk as many of his N (1 <= N <= 1,000) cows as possible. If the milked cows carry more than K (1 <= K <= D) different diseases among them, then the milk will be too contaminated and will have to be discarded in its entirety. Please help determine the largest number of cows FJ can milk without having to discard the milk.

Input

* Line 1: Three space-separated integers: N, D, and K

* Lines 2..N+1: Line i+1 describes the diseases of cow i with a list of 1 or more space-separated integers. The first integer, d_i, is the count of cow i's diseases; the next d_i integers enumerate the actual diseases. Of course, the list is empty if d_i is 0.

Output

* Line 1: M, the maximum number of cows which can be milked.

Sample Input

  1. 6 3 2
  2. 0
  3. 1 1
  4. 1 2
  5. 1 3
  6. 2 2 1
  7. 2 2 1

Sample Output

  1. 5

Hint

OUTPUT DETAILS:

If FJ milks cows 1, 2, 3, 5, and 6, then the milk will have only two diseases (#1 and #2), which is no greater than K (2).

 
 
输入案例的意思是
 有N头牛,它们可能患有D种病,现在从这些牛中选出若干头来,但选出来的牛患病的集合中不过超过K种病.
  1. 6 3 2 N,Dk
  2. 0 第一列是奶牛携带的疾病个数,后面表示疾病的种类
  3. 1 1
  4. 1 2
  5. 1 3
  6. 2 2 1
  7. 2 2 1 携带两种疾病,种类为12两类
 
题解:
这个题,枚举子集,真想说一句我真是日了狗了,搜集了一上午二进制法生成子集的东西才明白一点,现在算是会用一点了,简单介绍一下
这道题的的奶牛个数较小只有0-15,所以采用二进制的方法        
生成子集的二进制法:二进制中只有0和1两个数字。用二进制表示子集,从右到左第i位表示元素i是否在集合中。
        然后好对集合进行操作,通过为运算符实现,二元位运算:与(&),或(|),非(!)对应的是集合的交,或和对称差。

x&=(x-1)表示将x转化为2进制,最低的为1的位变成0,看含有的1的个数。

  1. 这是“位运算”中的一种很经典的用法,“&”是“与”的意思。它具体点的意思就是把x的二进制表示数最右边的一个1变成0 例如:
  2. e1:
  3. x = 01001000
  4. x-1 = 01000111
  5. x&(x-1)= 01000000
  6. e2:
  7. x = 01001001
  8. x-1 = 01001000
  9. x&(x-1)= 01001000
  1. 可见只有前后xx-1中的两个运算数都是 1 的时候结果才是1.
    同理“|”运算也是两个运算数有一个为1就是1.
    具体解释在代码中
  2.  
  3. AC代码:
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. int n,d,k;
  6. int N[+];
  7. bool judge(int x)
  8. {
  9. int c=;
  10. while(x)
  11. {
  12. c++; // 将x转化为2进制,看含有的1的个数。
  13. x&=(x-); //将最低的为1的位变成0
  14. }
  15. if(c<=k) //限制个数
  16. return ;
  17. else
  18. return ;
  19. }
  20. int main()
  21. {
  22. int s,t,total=;
  23. scanf("%d%d%d",&n,&d,&k);
  24. for(int i=; i<n; i++)
  25. {
  26. cin>>s;
  27. for(int j=; j<s; j++)
  28. {
  29. cin>>t;
  30. N[i]|=<<(t-); //1<<t-1(1的二进制数整体向左移t-1位)
  31. //一起把二进制数的位数对应着来看,这两个数在这一位上有1的结果就是1,否则是0
  32.  
  33. }
  34. }
  35. for(int i=; i<(<<d); i++) //i<(1<<d)是当i不小于(1左移d位的数)时终止循环,枚举各子集对应的编码0,1,2,..2^d-1
  36. {
  37. if(judge(i))
  38. {
  39. int f=;
  40. for(int j=; j<n; j++)
  41. {
  42. if((N[j]|i)==i) f++; //对应N[j]与i的并集与i相等,说明N[j]是它的子集
  43. }
  44. if(f>total)
  45. total=f;
  46. }
  47. }
  48. cout<<total<<endl;
  49. return ;
  50. }
 
 
 
 
 
 

BZOJ 1688: Disease Manangement (子集枚举)的更多相关文章

  1. 1688: [Usaco2005 Open]Disease Manangement 疾病管理( 枚举 )

    我一开始写了个状压dp..然后没有滚动就MLE了... 其实这道题直接暴力就行了... 2^15枚举每个状态, 然后检查每头牛是否能被选中, 这样是O( 2^15*1000 ), 也是和dp一样的时间 ...

  2. 1688: [Usaco2005 Open]Disease Manangement 疾病管理

    1688: [Usaco2005 Open]Disease Manangement 疾病管理 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 413  So ...

  3. 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP

    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...

  4. 【最小生成树+子集枚举】Uva1151 Buy or Build

    Description 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q< ...

  5. UVA11825 黑客的攻击 Hackers' Crackdown 状压DP,二进制,子集枚举

    题目链接Click Here [题目描述] 假如你是一个黑客,侵入了一个有着\(n\)台计算机(编号为\(1.2.3....n\))的网络.一共有\(n\)种服务,每台计算机都运行着所有服务.对于每台 ...

  6. BZOJ1688 Disease Manangement 疾病管理

    Disease Manangement 疾病管理   Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D ...

  7. BZOJ 1688: [Usaco2005 Open]Disease Manangement 疾病管理 状压DP + 二进制 + 骚操作

    #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #defin ...

  8. BZOJ 1688: [Usaco2005 Open]Disease Manangement 疾病管理

    Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) is running through the fa ...

  9. 【BZOJ】1688: [Usaco2005 Open]Disease Manangement 疾病管理(状压dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1688 很水的状压.. 提交了很多次优化的,但是还是100msT_T #include <cst ...

随机推荐

  1. bzoj1433 [ZJOI2009]假期的宿舍(最大流)

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1717  Solved: 754[Submit][Stat ...

  2. javaIO流小结(1)

    UTF-8的字节占多少个字节? 常用中文字符用utf-8编码占用3个字节(大约2万多字),超大字符集中要占4个字节.在内存中是2个字节,真正写到硬盘上面的是3个字节. GBK.GB2312汉字占2个字 ...

  3. Unity3d个人信息开发流程

    1.首先先对需要交互的属性进行G/S,比如声明金币的属性 private int _coin; public String Coin{ get{ return _coin; } set{ return ...

  4. bzoj1036 zjoi2008 树的统计 count

    填坑= =第一道裸树剖 #include<cstdio> #include<algorithm> #include<cstring> #include<cst ...

  5. Spring Boot(spring mvc升级版)

    周末挤出了一些时间,学了点东西,总结了一下,可能还有自己理解不到位的地方,希望大家一起交流学习,好东西要大家一起分享嘛~.时间有点紧张,所以样式没有来及做很好的调整,大家就凑活着看吧. Spring ...

  6. [PWA] 4. Hijacking Request

    We want to do offline first, the first thing we need to do is we should able to catch the browser re ...

  7. Android应用打包安装过程具体解释

    Android应用打包安装过程(Run as Android Application ): 1,过程:Android Project --> Compilation and Packaging ...

  8. NETSH WINSOCK RESET这条命令的含义和作用?

    简单来说netsh winsock reset命令含义是重置 Winsock 文件夹.假设一台机器上的Winsock协议配置有问题的话将会导致网络连接等问题,就须要用netsh winsock res ...

  9. linux sysvinit与upstart [转]

    linux sysvinit与upstart(1) linux sysvinit与upstart(2) linux sysvinit与upstart(3)

  10. uva 1391 Astronauts(2-SAT)

    /*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #inc ...