POJ 2184(01背包)(负体积)

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

http://blog.csdn.net/liuqiyao_01/article/details/8753686

对于负体积问题,可以先定义一个“零点”shift,将dp[shift]设为0,其他都设为-INF。

然后负体积从0往maxn+cost更新,正体积从maxn往shift更新。

最后从shift到maxn中找最大值,shift以下的值不会被遍历到

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;

#define MEM(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define debug printf("!
")
#define INF (0x3f3f3f3f)
#define MAX(a,b) a>b?a:b
#define blank pf("
")
#define LL long long
#define ep 1e-6

const int shift = 10000;
const int MAXN  = 210000;
const int MAXM = 105;

int dp[MAXN];

int ci[MAXM];//容量
int wi[MAXM];//价值
int n,V,i,j,v,t,sum;
double G;


void zeroOnePack(int cost,int weight)
{
          if(cost>=0)
          {
                    for(v = MAXN-1;v>=cost;v--)
                    {
                              dp[v] =MAX(dp[v],dp[v-cost]+weight);
                    }
          }
          else
          {
                    for(v = 0;v<MAXN+cost;v++)
                    {
                              dp[v] =MAX(dp[v],dp[v-cost]+weight);
                    }
          }
}

int main()
{
          while(sf("%d",&n)!=EOF)
          {

                    MEM(dp,-INF);
                    MEM(wi,0);

                    for(i = 0;i<n;i++)
                    {
                              sf("%d",&ci[i]);
                              sf("%d",&wi[i]);
                    }

                    dp[shift] = 0;

                    for(i = 0;i<n;i++)
                    {
                              zeroOnePack(ci[i],wi[i]);
                    }

                    int ans = -INF;

                    for(i = shift;i<MAXN;i++)
                    {
                              if(dp[i]>=0 && (i-shift+dp[i])>ans)
                                        ans = i-shift+dp[i];
                    }
                    pf("%d
",ans);



          }
    return 0;
}
/*
5
-5 7
8 -6
6 -3
2 1
-8 -5
*/
原文地址:https://www.cnblogs.com/qlky/p/5037522.html