标签:mem asn follow chm can space fuse country miss
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 6981 Accepted Submission(s): 2916
与顺序有关的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]小的先被”挑选“,差值越小使用它的价值越大(做出的牺牲越小).
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,f[5050]; struct nond{ int p,q,v; }num[550]; int cmp(nond a,nond b){ return a.q-a.p<b.q-b.p; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%d%d%d",&num[i].p,&num[i].q,&num[i].v); sort(num+1,num+1+n,cmp); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) for(int j=m;j>=num[i].q;j--) f[j]=max(f[j],f[j-num[i].p]+num[i].v); printf("%d\n",f[m]); } }
标签:mem asn follow chm can space fuse country miss
原文地址:http://www.cnblogs.com/cangT-Tlan/p/7435326.html