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\n", res); } return 0; }