HDU 3466(01背包变种

http://acm.hdu.edu.cn/showproblem.php?pid=3466

http://www.cnblogs.com/andre0506/archive/2012/09/20/2695841.html

这道题多了一个限制条件Qi,低于Qi时不能购买。

解题思路是看更新量,因为限制条件限制的是更新量。

比如一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m],再对第二个进行背包的时候,如果是普通的,应该会借用前面的dp[8],dp[7]之类的,但是现在这些值都是0,所以会导致结果出错。

于是要想到只有后面要用的值前面都可以得到,那么才不会出错。设A:p1,q1 B:p2,q2,如果先A后B,则至少需要p1+q2的容量,如果先B后A,至少需要p2+q1的容量,那么就是p1+q2 > p2+q1,变形之后就是q1-p1 < q2-p2。

另外注意qsort的cmp的格式是(const void*,const void*),返回的是两个值相减

#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("!/n")
#define INF 5050
#define MAX(a,b) a>b?a:b
#define blank pf("
")
#define LL long long

const int maxn = 550;

int dp[INF];

int n,V,i,j,v,tmp;

typedef struct
{
          int ci,wi,q;
}G;

G g[maxn];

int cmp(const void *a,const void *b)
{
          G *aa = (G *)a;
          G *bb = (G *)b;
          return (aa->q-aa->ci) - (bb->q-bb->ci);
}


void zeroOnePack(int cost,int weight)
{
          for(v = V;v>=g[i].q && v>=cost;v--)
          {
                    dp[v] =MAX(dp[v],dp[v-cost]+weight);
          }
}


int main()
{

          while(sf("%d%d",&n,&V)!=EOF)
          {
                    MEM(dp,0);
                    MEM(g,0);

                    for(i = 1;i<=n;i++)
                    {
                              sf("%d",&g[i].ci);
                              sf("%d",&g[i].q);
                              sf("%d",&g[i].wi);
                              if(g[i].q>V)
                                        i--,n--;
                    }

                    qsort(g+1,n,sizeof(g[1]),cmp);


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

                    pf("%d
",dp[V]);
          }
    return 0;
}
原文地址:https://www.cnblogs.com/qlky/p/5040317.html