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; }