POJ2184 01背包变形 xingxing在努力

           这道题乍一看就有了思路,大体就是定了其中一个值然后再求另外一个值的最大值, 然而代码实现好坑, 题意是奶牛有两个属性 Ai和Bi, 让你求Ai和Bi和的最大值,注意Ai的和不能为负整数, Bi也一样。。假设我们定了Ai我们来看下状态方程:f[i][j] = max(f[i-1][j], f[i-1][j-A[i]]+B[i])。当A[i]为正的时候就是我们经常遇到的01背包,使用滚动数组倒着排一遍, 然而当A[i]为负的时候我们就应该从小推到大,这样才对。。代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
const int inf = 0x3f3f3f3f;
int M = 100000;
int f[200000 + 10];
int A[100 + 10], B[100 + 10]; 

int main()
{
    int n;
    while(scanf("%d", &n) == 1)
    {
        for(int i=1; i<=n; i++)
            scanf("%d%d", &A[i], &B[i]);
        for(int i=0; i<=2*M; i++)
            f[i] = -inf;
        f[M] = 0;
        for(int i=1; i<=n; i++)
        {
            if(A[i] >= 0)
            {
                for(int j=2*M; j>=A[i]; j--)
                    f[j] = max(f[j], f[j-A[i]]+B[i]);
            }
            else 
            {
                for(int j=0; j<=2*M+A[i]; j++)
                    f[j] = max(f[j], f[j-A[i]]+B[i]);
            }
        }
        int res = 0;
        for(int i=M; i<=2*M; i++)
            if(f[i] >= 0)
                res = max(res, i-M+f[i]);
        printf("%d
", res);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xingxing1024/p/5001601.html