HDU 2602 Bone Collector(01背包)

Bone Collector

  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

解题思路:
  本题给出测试数量,每组测试给出骨骼数量n与背包体积v,之后跟随两行,第一行为骨骼的价值,第二行为骨骼的体积。要求输出背包所能装下骨骼的最大价值。

  本题是标准的0 1背包问题。基本思路是动态规划,令dp[ j ]表示背包容量为j时能装下骨骼的最大价值。

  对于第i块骨骼,有拿或不拿两种方案。

  1、拿第 i 块骨骼,问题转化为计算背包容量为j - volume[ i ] 在前i - 1块骨骼中取得最大价值问题dp[ j ]的值为前i - 1块骨骼中取得的最大价值 + 第i块骨骼的价值。

  2、不拿第i块骨骼,问题转化为背包容量为 j 时在前i - 1块骨骼中取得最大价值问题,dp[ j ]的值为前i - 1块骨骼中取得的最大价值。

  可以写出状态转移方程:dp[ j ] = max(dp[ j ], dp[ j - volume[ i ] ] + value[ i ])

  边界为拿前0块骨骼,最大价值为0,枚举所有骨骼,每次从最大背包容量开始逆序枚举便可获得答案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e3+100;
 4 int value[maxn], volume[maxn];
 5 //value记录骨骼价值volume记录骨骼体积
 6 int dp[maxn];
 7 int main()
 8 {
 9     int t;  //测试数量
10     while(scanf("%d", &t) != EOF){
11         int n, v;   //n为骨骼数量 v背包容量
12         while(t--){
13             scanf("%d%d", &n, &v);
14             for(int i = 1; i <= n; i++){
15                 scanf("%d", &value[i]); //输入骨骼价值
16             }
17             for(int i = 1; i <= n; i++){
18                 scanf("%d", &volume[i]);    //输入骨骼体积
19             }
20             memset(dp, 0, sizeof(dp));  //初始化边界
21             for(int i = 0; i <= n; i++){    //枚举骨骼
22                 for(int j = v; j >= volume[i]; j--){  //逆序枚举体积  
23                     dp[j] = max(dp[j], dp[j - volume[i]] + value[i]);
24                 }
25             }
26             int ans = 0;
27             for(int i = 0; i <= v; i++){    //找到最大值
28                 ans = max(ans, dp[i]);
29             }
30             printf("%d\n", ans);
31         }
32     }
33     return 0;
34 }

 

posted @ 2018-11-08 21:52  suvvm  阅读(243)  评论(0编辑  收藏  举报