zoukankan      html  css  js  c++  java
  • hdu_3466(01背包)

    其实,就是让C商品的q不等于p,其他都相同,这时,你就会发现如果要买C商品的话,肯定得先买C商品,因为买C商品的代价最大。所以,我们可以按照qi-pi的顺序来确定大顺序。这里我们还可以用更严谨的方式来证明一下,比如A:p1 q1, B:p2 q2,然后,假设单独买A或者B的话,都是可以买到的。这时,若先买A,则你至少需要p1+q2的钱;若先买B,则至少需要p2+q1的钱。那肯定是花最少的钱咯,所以如果先买A再买B,那么p1+q2<p2+q1,转换一下,就是q1-p1>q2-p2,也就是说qi-pi大的先买。这里还得注意一点就是,排序的时候,得按照qi-pi从小到大排序,因为你买第n件商品的时候,是在比较你是否要先买第n件商品。打个比方让大家更好地理解,比如说f(3, 10),是不是max(f(2, 10-p3)+v3, f(2, 10)),你会发现这个第一种情况f(2,10-p3)+v3中,是先买了第三件商品,也就是说排在后面的商品会先买。好的,排好序之后,就把问题就转换为不需要考虑顺序的问题了,那就是解决0/1背包问题了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct item{
     6     int p;
     7     int q;
     8     int v;
     9 } I[550];
    10 bool cmp(item a,item b){
    11     return a.q-a.p < b.q-b.p;
    12 }
    13 int dp[5550];
    14 int main()
    15 {
    16     int n,m;
    17     while(~scanf("%d%d",&n,&m)){
    18         memset(dp,0,sizeof(dp));
    19         for(int i = 0; i < n; i++){
    20             scanf("%d%d%d",&I[i].p,&I[i].q,&I[i].v);
    21         }
    22         sort(I,I+n,cmp);
    23         for(int j = 0;j < n ;j++){
    24             for(int i = m; i >= max(I[j].q,I[j].p); i--){
    25                 dp[i] = max(dp[i],dp[i-I[j].p]+I[j].v);
    26             }
    27         }
    28         printf("%d
    ",dp[m]);
    29     }
    30 
    31     return 0;
    32 }
  • 相关阅读:
    JavaScript基本语法2
    JavaScript的基本语法
    在网页中加入神奇的效果
    一个由表单构成的页面
    进程理论要点
    TCP大文件上传与UDP协议
    socket编程相关阐述
    网络编程
    魔法方法
    元类与单例解析
  • 原文地址:https://www.cnblogs.com/shanyr/p/11823633.html
Copyright © 2011-2022 走看看