• 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
    ", ans);
    31         }
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    cout的输出格式初探
    CVPR 2015 papers
    C语言的32个保留字
    读取siftgeo格式文件的matlab程序
    (转)各类排序算法总结
    被除数、除数、商、余数的正负号规律二
    被除数、除数、商、余数的正负号规律一
    FCKEditor上传图片word
    CKEditor上传图片word
    在线编辑器上传图片word
  • 原文地址:https://www.cnblogs.com/suvvm/p/9932291.html
Copyright © 2020-2023  润新知