标签:
解题思路:与顺序有关的01背包。初看之下似乎和普通背包差不多,判容量大于q时才装。但是这会出大问题,如果一个物品p = 5,q = 7,一个物品p = 5,q = 9,如果先算第一个,那么当次只有7,8...m可以进行状态转移,装第二个物品的时候9,10..m进行转移,第二个物品转移就可以借用第一个物品的那些个状态,而第二个物品先转移,第一个再转移则不能。当然,还有价格有关,当限制一样价格不同时顺序就影响结果。一种组合的排序策略--限制又小价格又贵的先选,也就是q-p小的先选。为什么这样呢?A:p1,q1 B: p2,q2,先选A,则至少需要p1+q2的容量,而先选B则至少需要p2+q1,如果p1+q2>p2+q1,那么要选两个的话的就要先选A再选B,公式可换成q1-p1 < q2-p2,就按这样的方法排序最后的顺序就是最优的顺序。
该题要确保P[i]-Q[i]小的先被”挑选“,差值越小使用它的价值越大(做出的牺牲越小).
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #define MAX(x,y)(x>y?x:y) 5 const int MAXN=5010; 6 const int MAXM=510; 7 struct Node{ 8 int p,q,v; 9 }; 10 int cmp(const void *a,const void *b){ 11 if((*(Node *)a).q-(*(Node *)a).p<(*(Node *)b).q-(*(Node *)b).p)return -1; 12 else return 1; 13 } 14 Node dt[MAXM]; 15 int bag[MAXN]; 16 int main(){ 17 int N,M; 18 while(~scanf("%d%d",&N,&M)){ 19 memset(bag,0,sizeof(bag)); 20 for(int i=0;i<N;i++)scanf("%d%d%d",&dt[i].p,&dt[i].q,&dt[i].v); 21 qsort(dt,N,sizeof(dt[0]),cmp); 22 for(int i=0;i<N;i++) 23 for(int j=M;j>=dt[i].q;j--){// 24 if(j>=dt[i].p){// 25 bag[j]=MAX(bag[j],bag[j-dt[i].p]+dt[i].v); 26 } 27 } 28 printf("%d\n",bag[M]); 29 } 30 return 0; 31 }
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/4761578.html