Bone Collector 0-1背包问题
Posted -y-i-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bone Collector 0-1背包问题相关的知识,希望对你有一定的参考价值。
题目描述:
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 ?
输入:
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.
输出:
One integer per line representing the maximum of the total value (this number will be less than 2 31).
样例:
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
14
题目大意:
有一个人喜欢收集骨头(呃),现在有N根骨头,每根骨头对应着各自的体积和价值,这个人的背包容量为V,求能装的骨头的最大总价值。
代码:
#include<iostream> #include<stdio.h> #define max(a,b) a>b?a:b struct bone{ int wei,val; }; int f[1002][1002]; bone temp[1005]; int value(int num,int v){ for(int i=1;i<=num;++i){ for(int j=0;j<=v;++j){ if(j<temp[i-1].wei) f[i][j]=f[i-1][j]; else f[i][j]=max(f[i-1][j-temp[i-1].wei]+temp[i-1].val,f[i-1][j]); } } return f[num][v]; } using namespace std; int main(){ int n,num,v; scanf("%d",&n); for(int i=0;i<n;++i){ scanf("%d%d",&num,&v); for(int j=0;j<num;++j) scanf("%d",&temp[j].val); for(int j=0;j<num;++j) scanf("%d",&temp[j].wei); printf("%d ",value(num,v)); } return 0; }
这是一道0-1背包问题,要解决的问题就是要放哪些物品进背包,总价值是多少。
而对于每一个物品只有放与不放两种情况:
1. 第i件放进去:价值为:f[i-1][v-temp[i-1].wei]+temp[i-1].val(背包容量减去第i件物品的体积,再加上对前i-1件进行判断后得到价值的最大值(容量为v-temp[i-1].wei的背包))
2. 第i件不放进去:价值为:f[i-1][v](容量不减少(为v),对前i-1件进行判断后得到价值的最大值)
状态转移方程为:f[i][v] = max(f[i-1][v], f[i-1][v-w[i]]+c[i])
随后对两种情况取较大值。第一行初始化为0.从第一个物品开始列表记录背包容量内剩余不同容积存放前i个物品情况的最大值。
这个解法比较容易理解,下面的链接有对背包问题更详尽的解释,受启发于此:
https://www.cnblogs.com/A-S-KirigiriKyoko/p/6036368.html
https://www.cnblogs.com/xym4869/p/8513801.html
(其中的代码将第一列也初始化为0,这样子的话当物品中同时存在体积=背包容量的物品和体积=0的物品时就会出错,因此稍作改动)
以上是关于Bone Collector 0-1背包问题的主要内容,如果未能解决你的问题,请参考以下文章
hdu2602Bone Collector ——动态规划(0/1背包问题)
hdoj2602 Bone Collector(DP,01背包)