zoukankan      html  css  js  c++  java
  • hdu 2602 Bone Collector 解题报告

       题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

       在没学01背包时做的,很遗憾的是,wa了很多次。

       wa代码 

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 struct back
     6 {
     7     int value;
     8     int volume;
     9 } backet[1005];
    10 
    11 int cmpvalue(back a, back b)
    12 {
    13     return a.value > b.value;
    14 }
    15 
    16 int main()
    17 {
    18     int T, i, j, n, v, sumvalue, sumvolume, maxvalue;
    19     while (cin >> T)
    20     {
    21         while (T--)
    22         {
    23             cin >> n >> v;
    24             for (i = 0; i < n; i++)
    25                 cin >> backet[i].value;
    26             for (j = 0; j < n; j++)
    27                 cin >> backet[j].volume;
    28             sort(backet, backet+n, cmpvalue);  //按价值递减的顺序排列,保证下面的是从最大价值的物品开始试探的
    29             maxvalue = sumvalue = sumvolume = 0;
    30             for (i = 0; i < n; i++)
    31             {
    32                 sumvalue += backet[i].value;
    33                 sumvolume += backet[i].volume;
    34                 if (sumvalue > maxvalue && sumvolume <= v) //比当前最大价值大的话则更新maxvalue
    35                 {    
    36                     maxvalue = sumvalue;    
    37                 }
    38                 else        // 比当前最大价值小的话则不装载到背包里,即回退到上一个状态(未装载前)
    39                 {
    40                     sumvalue -= backet[i].value;
    41                     sumvolume -= backet[i].volume;
    42                 }
    43                 
    44             }
    45             printf("%d\n", maxvalue);
    46         }
    47     }
    48     return 0;
    49 }

          在乌东兄的悉心指导下,终于知道如何错了......

          此为贪心法,但是不能保证得出来最终结果是最优的。例如这个例子:

          1
          3  4
          4  3  2
          3  2  2

           如果用贪心做的话,它第一个取的是最大的价值4,花费的容量为3,那么剩下的背包容量只有1,后面的物品不能够再装载,因为最少的花费2都比1大。而最大的价值应该是5,花费的容量恰好为给定的容量限制4      

           于是改用DP方法(自数塔(非常好理解)、最少拦截系统(看书看到的,但不太明白))来做,前面的介绍还是比较容易理解的,但是到了空间优化第二个循环为什么是反向的就很难理解了,通过笔算模拟,有点明白了。以下是摘自大神乌东兄的语录(应该不会怪我的,无请示就....):

         dp数组当前储存的是用前 0..i - 1 个物品构造的 0..V 容量的最优值。
         如果内循环系正向,假设计算 dp[j] 时选择了放入物品 i ,
        计算第 dp[ j + costi ] 时,也选择嘞放入物品 i, 这样物品 i 就用了多次。
        由于 dp[j] 的推导会与 dp[0 .. j - 1] 有关,如果内循环反向的话,可以保证
        dp[ 0.. j - 1 ] 不包含物品 i ,即保证物品只用鸟 一次。

         AC代码:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int i, j, T, N, V, c[1005], w[1005], dp[1005];
     7     while (cin >> T)
     8     {
     9         while (T--)
    10         {
    11             memset(dp, 0, sizeof(dp));
    12             cin >> N >> V;
    13             for (i = 0; i < N; i++)    
    14                 cin >> w[i];
    15             for (i = 0; i < N; i++)
    16                 cin >> c[i];
    17             for (i = 0; i < N; i++)
    18             {
    19                 for (j = V; j >= c[i]; j--)    //关键所在,如果正向,会使得一个物品可能被用多次
    20 { 21 dp[j] = (dp[j] >= dp[j-c[i]] + w[i] ? dp[j]: dp[j-c[i]]+w[i]); 22 } 23 } 24 printf("%d\n", dp[V]); 25 } 26 } 27 return 0; 28 }

       

  • 相关阅读:
    Spring 中出现Element : property Bean definitions can have zero or more properties. Property elements correspond to JavaBean setter methods exposed by the bean classes. Spring supports primitives, refer
    java定时器schedule和scheduleAtFixedRate区别
    hql语句中的select字句和from 字句
    使用maven搭建hibernate的pom文件配置
    Failure to transfer org.apache.maven:maven-archiver:pom:2.5 from http://repo.maven.apache.org/ maven2 was cached in the local repository, resolution will not be reattempted until the update interv
    对于文件File类型中的目录分隔符
    hibernate的事务管理和session对象的详解
    解决mac 中的myeclipse控制台中文乱码问题
    ibatis selectKey用法问题
    Java中getResourceAsStream的用法
  • 原文地址:https://www.cnblogs.com/windysai/p/3091514.html
Copyright © 2011-2022 走看看