您的位置:首页 > 其它

POJ 2184 Cow Exhibition(01背包问题)

2015-10-09 20:27 411 查看
Description

有一些奶牛,他们有一定的s值和f值,这些值有正有负,最后让保证s的和为非负且f的和为非负的情况下,s+f的最大值

Input

第一行为奶牛数量n,之后n行每行两个整数表示对应奶牛的s和f值

Output

输出保证s和非负f和非负时的s+f的最大值

Sample Input

5

-5 7

8 -6

6 -3

2 1

-8 -5

Sample Output

8

Solution

将s+100000看作重量,f看作价值,问题转化为01背包问题,最后取dp[i]+i-100000(100000 <=i<=200000,dp[i]>=0)的最大值即可,注意由于01背包省略第一维后为避免后效性,内层循环都是逆着推的,因此s值为负时内层循环方向与s值为正时相反

Code

#include<stdio.h>
#define maxn 100000
#define INF 1<<30
#define max(x,y) ((x)>(y)?(x):(y))
int dp[2*maxn+10],n,s[101],f[101];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d%d",&s[i],&f[i]);
for(int i=0;i<=2*maxn;i++)//初始化
dp[i]=-INF;
dp[maxn]=0;
for(int i=1;i<=n;i++)//01背包
{
if(s[i]<0&&f[i]<0)//剪枝
continue;
if(s[i]>=0)
{
for(int j=2*maxn;j>=s[i];j--)
if(dp[j-s[i]]>-INF)
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}
else
{
for(int j=s[i];j<=2*maxn+s[i];j++)//注意循环方向
if(dp[j-s[i]]>-INF)
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}
}
int ans=-INF;
for(int i=maxn;i<=2*maxn;i++)//满足s和非负
if(dp[i]>=0)//满足f和非负
ans=max(ans,dp[i]+i-maxn);//更新s+f最大值
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: