poj2184 Cow Exhibition(01背包+变化)

来源:互联网 发布:黑马python百度云 编辑:程序博客网 时间:2024/05/17 06:42

poj2184

分析

这道题首先用dp[i]存放每个s[i]的f值,开二维或者三维都不可接受,但是s[i]的值可以为负,数组是从0开始的,所以我们将i值扩大,原来-100000~100000的范围变为0~200000.对于s[i]为正的情况,也就是01背包,当前状态是由之前状态转移而来,因为s[i]为正,所以是从比自己小的得来,保证比自己小的还没有更新过,循环从大到小,但是对于s[i]为负的情况,一个数加负数是变小的,所以之前状态是比自己大的,所以循环从小到大。最后再找到符合题意的最大值。
还真没有想到,对于状态为负而且这个状态不能丢掉的处理,学习了。

题目

http://poj.org/problem?id=2184

代码

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=110;const int inf=0x3f3f3f3f;struct node{    int s,f;} cow[maxn];int dp[200010];int main(){    int n;    scanf("%d",&n);    for(int i=0; i<n; i++)        scanf("%d %d",&cow[i].s,&cow[i].f);    for(int i=0; i<=200000; i++)        dp[i]=-inf;    dp[100000]=0;    for(int i=0; i<n; i++)    {        int ss=cow[i].s,ff=cow[i].f;        if(ss<0&&ff<0)            continue;        if(ss>0)        {            for(int j=200000; j>=ss; j--)                if(dp[j-ss]>-inf)                    dp[j]=max(dp[j],dp[j-ss]+ff);        }        else        {            for(int j=0; j<=200000+ss; j++)                if(dp[j-ss]>-inf)                    dp[j]=max(dp[j],dp[j-ss]+ff);        }    }    int ans=-inf;    for(int i=100000;i<=200000;i++)    {        if(dp[i]>=0)            ans=max(ans,dp[i]+i-100000);    }    printf("%d\n",ans);    return 0;}
0 0