题目链接:

​http://acm.hdu.edu.cn/showproblem.php?pid=4152​


题目大意:

ZZY有N个目标,每个目标都有一个分数值,只有达到给定的分数值才算完成目标。他有M

个习惯。每个习惯对这N个目标有影响xi,xi >= 0,表示对目标有积极作用,xi < 0表示对

目标有消极作用。现在问:如果ZZY想实现这N个目标,他能够有的习惯数目最大是多少,

并输出能够有的习惯编号。


思路:

用0和1来表示选和不选习惯i,则有2^M种情况(最多为2^16 = 65536)。枚举得到结果。用

Goal[]存储目标分数,F[i][j]来存储第 i 习惯对第 j 个目标的影响。G[]存储不同习惯情况下,

第 i 项目标的得到的分数。求出满足要求最大的情况。


AC代码:


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int Goal[30];
int F[30][30],G[30];

int main()
{
int N,M;
while(cin >> N)
{
int ans = -1,pos;
for(int i = 0; i < N; ++i)
cin >> Goal[i];
cin >> M;
for(int i = 0; i < M; ++i)
for(int j = 0; j < N; ++j)
cin >> F[i][j];
for(int i = 1; i < (1<<M); ++i)
{
memset(G,0,sizeof(G));
int Num = 0;
for(int j = 0; j < M; ++j)
{
if(i & (1<<j) ) //如果要第j个习惯
{
Num++;
for(int k = 0; k < N; ++k)
G[k] += F[j][k];
}
int kk;
for(kk = 0; kk < N; ++kk)
if(G[kk] < Goal[kk])
break;
if(kk >= N)
{
if(Num > ans)
{
ans = Num;
pos = i;
}
else if(Num == ans && pos > i)
pos = i;
}
}
}
if(ans == -1)
cout << "0" << endl;
else
{
cout << ans;
for(int i = 0; i < N; ++i)
if(pos & (1<<i))
cout << ' ' << i+1;
cout << endl;
}
}

return 0;
}