题目链接:http://poj.org/problem?id=2184
题目大意:牛类想要向世人证明他们聪明又幽默。经过测试,每头牛都有一个幽默度Fi和智商Si,现要求从N头牛中选择 若干头牛去参加比赛,假设这若干头牛的智商之和为sumS,幽默度之和为sumF 现要求在所有选择中,在使得sumS>=0&&sumF>=0的基础上,使得sumS+sumF最大并输出其值。
思路:先求出不同体积下的最大价值。然后在用一个for循环,寻找 体积+价值 = 最大 的情况。需要注意费用为负值是的遍历方向改变。
参考链接:http://blog.csdn.net/actangy/article/details/7433992
#include <cstdio>
#include <cstring>
#define max(x,y) ((x)>(y)?(x):(y))
struct Point
{
int s,f;
}p[105];
int f[200010]; //100*1000*2,表示当s之和达到i时,f之和的最大值
int n;
void ZeroOnePack ()
{
int i,v;
for (i=1;i<=n;i++)
{
int &cost=p[i].s;
int &weight=p[i].f;
if (cost>0)
for(v=200000;v>=cost;v--) //从大向小遍历
f[v]=max(f[v],f[v-cost]+weight);
else
{
cost=-cost;
for(v=0;v+cost<=200000;v++) //从小向大遍历
f[v]=max(f[v],f[v+cost]+weight);
}
}
}
int Deal()
{
memset(f,0x8f,sizeof(f));
// for (int j=0;j<=200000;j++)
// f[j]=-1000000000;
f[100000]=0;
ZeroOnePack ();
int i,sum=0;
for (i=100000;i<=200000;i++)
if (f[i]>=0)
sum=max(sum,f[i]+i-100000);
return sum;
}
int main()
{
int T;
while (~scanf("%d",&T))
{
int a,b;
n=0;
for (int i=1;i<=T;i++)
{
scanf("%d%d",&a,&b);
if (a<0 && b<0) //这头牛肯定不会被考虑
continue;
else
{
n++;
p[n].s=a,p[n].f=b;
}
}
printf("%d\n",Deal());
}
return 0;
}