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

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 54132    Accepted Submission(s): 22670

Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 231).
Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1

Sample Output
14
01背包问题,这种背包特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即dp[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
则其状态转移方程便是:
dp[i][v]=max{dp[i-1][v],dp[i-1][v-cost[i]]+value[i]}
 1 #include<iostream>
 2 using namespace std;
 3 int dp[1000][1000];
 4
 5 int max(int x,int y)
 6 {
 7     return x>y?x:y;
 8 }
 9
10 int main()
11 {
12     int t,n,v,i,j;
13     int va[1000],vo[1000];
14     cin>>t;
15     while(t--)
16     {
17         cin>>n>>v;
18         for(i=1;i<=n;i++)
19             cin>>va[i];
20         for(i=1;i<=n;i++)
21             cin>>vo[i];
22         memset(dp,0,sizeof(dp));//初始化操作
23          for(i=1;i<=n;i++)
24         {
25             for(j=0;j<=v;j++)
26             {
27                 if(vo[i]<=j)//表示第i个物品将放入大小为j的背包中
28                     dp[i][j]=max(dp[i-1][j],dp[i-1][j-vo[i]]+va[i]);//第i个物品放入后,那么前i-1个物品可能会放入也可能因为剩余空间不够无法放入
29                 else //第i个物品无法放入
30                     dp[i][j]=dp[i-1][j];
31             }
32         }
33         cout<<dp[n][v]<<endl;
34     }
35     return 0;
36 }

该题的第二种解法就是对背包的优化解法,当然只能对空间就行优化,时间是不能优化的。

先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1..N,每次算出来二维数组dp[i][0..V]的所有值。
那么,如果只用一个数组dp[0..V],能不能保证第i次循环结束后dp[v]中表示的就是我们定义的状态dp[i][v]呢?

dp[i][v]是由dp[i-1][v]和dp[i-1][v-c[i]]两个子问题递推而来,能否保证在推dp[i][v]时(也即在第i次主循环中推dp[v]时)能够得到dp[i-1][v]和dp[i-1][v-c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推dp[v],这样才能保证推dp[v]时dp[v-c[i]]保存的是状态dp[i-1][v-c[i]]的值。伪代码如下:

for i=1..N

for v=V..0

dp[v]=max{dp[v],dp[v-c[i]]+w[i]};

注意:这种解法只能由V--0,不能反过来,如果反过来就会造成物品重复放置!

 1 #include<iostream>
 2 using namespace std;
 3 #define Size 1111
 4 int va[Size],vo[Size];
 5 int dp[Size];
 6 int Max(int x,int y)
 7 {
 8     return x>y?x:y;
 9 }
10 int main()
11 {
12     int t,n,v;
13     int i,j;
14     cin>>t;
15     while(t--)
16     {
17         cin>>n>>v;
18         for(i=1;i<=n;i++)
19             cin>>va[i];
20         for(i=1;i<=n;i++)
21             cin>>vo[i];
22         memset(dp,0,sizeof(dp));
23         for(i=1;i<=n;i++)
24         {
25             for(j=v;j>=vo[i];j--)
26             {
27                 dp[j]=Max(dp[j],dp[j-vo[i]]+va[i]);
28             }
29         }
30         cout<<dp[v]<<endl;
31     }
32     return 0;
33 }

转载于:https://www.cnblogs.com/yoke/p/6106079.html

hdu 2602 Bone Collector(01背包)模板相关推荐

  1. hdu 2602 Bone Collector 01背包

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

  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背包)

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

  4. hdu 2602 Bone Collector 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 在没学01背包时做的,很遗憾的是,wa了很多次. wa代码 1 #include <ios ...

  5. hdu 2602 Bone Collector

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

  6. HDU 2602 Bone Collector - from lanshui_Yang

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

  7. 01背包模板、全然背包 and 多重背包(模板)

    转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/ ...

  8. 最大报销额 HDU - 1864(DP+01背包)

    最大报销额 HDU - 1864 点击跳转↑ 题设:多组输入,每组输入一对Q和N,分别代表当前的公费,和需要报销的账单总数.接下来N行,每行开始一个m,接下来是m项物品的名称和价格.求:在所有符合报销 ...

  9. 01背包模板、完全背包 and 多重背包

    转载请注明出处:http://blog.csdn.net/u012860063 讲解链接:http://www.cppblog.com/tanky-woo/archive/2010/07/31/121 ...

最新文章

  1. 当所有人都向往大厂时,这些 00 后程序员却选择逃离
  2. 【C++】31. Boost::circular_buffer——循环缓冲区
  3. 疯狂ios讲义之疯狂连连看游戏简介
  4. 毕业典礼留学生代表发言:中国是我可亲可敬可爱的第二故乡,我已修炼出一颗中国心!...
  5. 恒企自考_致自考生:想自考的人千千万万,遇到的困难却千篇一律
  6. 动图处理_100+动图带你看懂百大加工工艺(成型、表面处理、链接、切割)
  7. 【GitHub】用Bash编写的 Linux 资源监视器
  8. MNIST手写数字数据集格式,如何读取MNIST数据集?
  9. 图解系列之JAVA执行过程
  10. 常见NetBackup通讯问题及排错一般步骤
  11. 关于WindowsPE的DIY和黑科技
  12. uva 12086 树状数组
  13. MacPorts 命令集合
  14. python语言实现指纹识别_Python语言之指纹识别是目前最成熟的识别技术!Python能分分钟做出一个来!...
  15. wifi动不动就断开_笔记本Wifi上网经常间歇性断网的修复
  16. 未来十大最热门职业,可能消失的职业
  17. 医学分子生物学试题答案
  18. 康德、孔子和休谟的对话
  19. 机器学习——霍夫丁不等式【转】
  20. 成立一家投资管理有限公司的资本是多少?

热门文章

  1. vue路由跳转 返回上一级 this.$router.go(-1) 和返回到指定页面this.$router.push('/home')...
  2. ScrollView 分割屏幕效果
  3. 常发生的异常有哪些, 如何使用异常?
  4. 百余名欧洲议会议员发函 呼吁英国留在欧盟
  5. Java类加载机制总结
  6. MongoDB(课时30 $group)
  7. win7系统下升级IE11
  8. Centos 开放端口
  9. 打造基于大并发通信技术及大数据技术的O2O系统
  10. Cannot resolve corresponding JNI function