题目链接: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 }

转载于:https://www.cnblogs.com/windysai/archive/2013/05/21/3091514.html

hdu 2602 Bone Collector 解题报告相关推荐

  1. hdu 2602 Bone Collector(01背包)模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/Ot ...

  2. HDU 2602 Bone Collector DP(01背包)

    Bone Collector Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

  3. hdu 2602 Bone Collector 01背包

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu 2602 Bone Collector

    终于开始做自己一直不敢碰的dp了,内心颇不平静.很久以前看过的背包九讲也没什么印象了.这个题错了四次.之前老师有说过看到dp不要把它想成dp,要按照数学归纳的路子来.先来个最初的归纳假设,如果过弱再加 ...

  5. HDU 2602 Bone Collector - from lanshui_Yang

           题目大意:有n件物品,每件物品均有各自的价值和体积,给你一个容量为 V 的背包,问这个背包最多能装的物品的价值是多少?        解题思路:这是一道0 - 1 背包的简单模板题,也是 ...

  6. hdu 2602 Bone Collector(01背包)

    题意:给出包裹的大小v,然后给出n块骨头的价值value和体积volume,求出一路下来包裹可以携带骨头最大价值 思路:01背包 1.二维数组(不常用 #include<iostream> ...

  7. HDU - 2639 Bone Collector II

    HDU - 2639 Bone Collector II dp之难,难于上青天. The title of this problem is familiar,isn't it?yeah,if you ...

  8. HD 2602 Bone Collector (0-1背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Problem Description Many years ago , in Teddy's ...

  9. 2602 Bone Collector

    题目详情: Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

最新文章

  1. Fedora 7 播放器totem
  2. 关于SWT开发的一个坑——Invalid thread access
  3. 关于arguments
  4. Greenplum小把戏 - 你所不知道的时间戳长度玩法
  5. 一个上帝视角的java游戏_从上帝视角看Java如何运行
  6. 从JDK源码看关闭钩子
  7. 两周从爬虫小白变大神,看完你就知道我不是标题党了【五万字教程,建议收藏】
  8. java项目连接Oracle配置文件
  9. linux工作技能第二发:vi
  10. 阿阿斯顿发沙发是地方撒旦法
  11. 非IE浏览器下ActiveX技术的替代方案
  12. 2分钟入侵网站全程实录
  13. 70%的开发者完全不懂或只了解云原生概念
  14. Python爬虫-字体反爬-猫眼国内票房榜
  15. Java+Selenium3方法篇43-利用Jexcel操作2003版本excel
  16. 微信“15。。。。。”背后的故事
  17. 第一次亲密接触IT技术(第一天)
  18. PLM与ERP集成,这个头疼的问题,可以这样解决!
  19. 初次学习HTML的感受
  20. BBS论坛项目总结(持更),附源码

热门文章

  1. RPC failed; curl 56 SSLRead() return error -9806
  2. 谁需要这件礼物?每一个爱学习的人!
  3. Office 2010 体验系列之Outlook使用
  4. [NOIP2003] 提高组 洛谷P1041 传染病控制
  5. .NET Core RSA 签名和验签(密钥为 16 进制编码)
  6. C# List 扩展排序
  7. 【CSS3】Advanced3:Universal, Child, and Adjacent Selectors
  8. vrrp 理论和配置
  9. 如何限制浏览器使用_如何使用浪涌电流限制器NTC(一)
  10. PL/SQL Developer 导入外部文件数据