POJ 2184 Cow Exhibition(01背包问题)

来源:互联网 发布:f450破解用户数软件 编辑:程序博客网 时间:2024/06/07 03:58

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;} 
0 0
原创粉丝点击