题意:每头牛有一个S值,F值。取几只牛,使这几只牛∑S和∑F大于0的条件下,∑S+∑F最大。
可以转化为01背包问题。S看做重量,F看做价值。由于S可能为负值,把数轴左移100000,以dp[100000]作为原点。最后从dp[100000]开始,dp[i]>0的即满足第一个条件,再找最大值。特别注意在s[i]为负值时从小到大遍历。
#include <cstdio>
#include <cstring>
const int MAX1=200010;
int dp[MAX1];
int s[108],f[108];
int main()
{
int N,i,j,ans;
scanf("%d",&N);
for(i=1;i<=N;i++)
scanf("%d%d",s+i,f+i);
for(i=0;i<=200000;i++)
dp[i]=-3000000;
dp[100000]=0;
for(i=1;i<=N;i++)
if(s[i]>0)
{
for(j=200000;j>=s[i];j--)
if(dp[j]<dp[j-s[i]]+f[i])
dp[j]=dp[j-s[i]]+f[i];
}
else
{
for(j=0;j<=200000+s[i];j++)
if(dp[j]<dp[j-s[i]]+f[i])
dp[j]=dp[j-s[i]]+f[i];
}
ans=0;
for(i=100000;i<=200000;i++)
if(dp[i]>0&&ans<dp[i]+i-100000)
ans=dp[i]+i-100000;
printf("%d\n",ans);
return 0;
}