ZZY的困惑
Description
ZZY有很多爱好~~比如足球、电影、三国杀、A题,而他希望在这些爱好中能收获一些东西~~但是并不是所有爱好对所有目标都是起积极作用的..ZZY十分的困惑..于是列了下自己想获得的收获并且给每个目标设立了最小要达到的权值...并且给自己的爱好对每个收获目标进行了评值..这个值若是负则代表不利于获得某个收获~~为0代表没影响~~为正的代表利于获得某种收获..现在ZZY已经制作好了这些数据想请你帮帮忙~~在保证所有的目标最低要求都能达成的情况下保留尽量多的爱好~~
Input
多组数据读到EOF结束(不超过10组)每组数据
第一行为ZZY的收获目标个数N ( 0<N<=20 )
第二行为ZZY对每个目标所订的一个最低权值 ( 0 < w <= 1000 )
第三行为ZYY的爱好总数M ( 0 < M <= 16 )
下面的M行每行有N个数代表每个爱好对每个目标的促进权值..( -1000 <= k <= 1000 )
Output
每组输入对应一行输出:
第一个数为能保留的最多爱好个数..紧接着为这些爱好分别对应输入的是那几个序号..
若有多种都能达到保留个数请输出相对来说较小的(如 1 2 与 3 4 同时能满足要求,那么选1 2)
若怎么都无法实现目标那只能说着所有爱好都要不得,输出0...
Sample Input
4 100 200 300 400 3 100 100 400 500 100 -10 50 300 100 100 -50 -50
Sample Output
2 1 3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #define maxn 22 4 5 int n,m; 6 int need[maxn]; 7 int sum[maxn][1<<16]; 8 int help[maxn][1<<16]; 9 10 bool check(int sta) 11 { 12 for(int i=0; i<n; i++) 13 { 14 if(sum[i][sta]<need[i]) 15 return false; 16 } 17 return true; 18 } 19 int lowbit(int x) 20 { 21 return x&-x; 22 } 23 int cnt[1<<16]; 24 25 int main() 26 { 27 int i,j,k; 28 cnt[0]=0; 29 int all=(1<<16); 30 for(i=1; i<all; i++) cnt[i]=cnt[i-lowbit(i)]+1; 31 while(~scanf("%d",&n)) 32 { 33 for(i=0; i<n; i++) scanf("%d",&need[i]); 34 scanf("%d",&m); 35 for(i=0; i<m; i++) 36 for(j=0; j<n; j++) scanf("%d",&help[j][1<<i]); 37 memset(sum,0,sizeof(sum)); 38 int maxret=0,ret=0; 39 for(i=1; i<(1<<m); i++) 40 { 41 int x=lowbit(i); 42 for(j=0; j<n; j++) sum[j][i]=sum[j][i-x]+help[j][x]; 43 if(check(i)) 44 if(cnt[i]>maxret) 45 { 46 maxret=cnt[i]; //cnt[i]记录爱好的个数 47 ret=i; //ret利用二进制压缩法记录爱好的次序 48 } 49 } 50 printf("%d",maxret); 51 for(i=0; i<m; i++) 52 { 53 if(ret&(1<<i)) 54 printf(" %d",i+1); 55 } 56 puts(""); 57 } 58 return 0; 59 }