Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 58027 Accepted Submission(s): 24207
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 ?
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.
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 2
31).
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
14
Author
Teddy
Source
Recommend
做的第一道01背包题。
题意:骨头收集者!!骨头都有自己的value(价值)和volume(体积),现在给一个一定容积的袋子,问如何装才能装下最大价值的骨头。典型的01背包问题。以下列程序为例,若以二维数组d[1005][1005]来记录01背包表的值的话,动态方程为d[i][j]=max(d[I-1][j],d[I-1][j-b[I]]+a[I])以题目给定例子来画出下面的01背包表:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 0 | 0 | 0 | 2 | 2 | 2 | 2 | 2 | 3 | 3 |
3 | 0 | 0 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 |
4 | 0 | 4 | 4 | 4 | 7 | 7 | 7 | 7 | 10 | 10 |
5 | 5 | 5 | 9 | 9 | 9 | 12 | 12 | 12 | 12 | 14 |
该表的第一行表示背包的大小j,第一列表示物品的价值a[I],这个表造成的疑问在于,列如为什么d[1][9]不是价值为1的物品加上价值为2的物品,他们的体积相加刚好是9啊!?这是因为在I=1这行,没有轮到价值大于1的物品来排。也就是说,第I行就是价值为1~I的物品去进行装填。按照这个道理,右下角最后一个格子里的就是我们要求的最大值。或许还是没懂,其实自己亲自把表里的值推推就会好些了。
原理懂了之后编程是水到渠成啊!
附上代码:
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int a[1005],b[1005];
int d[1005][1005];
int main()
{
int n;
cin>>n;
while(n--)
{
memset(d,0,sizeof(d));
int x,y;
cin>>x>>y;
for(int i=1;i<=x;i++)
cin>>a[i];///价值
for(int i=1;i<=x;i++)
cin>>b[i];///所占空间
for(int i=1;i<=x;i++)///动态规划
{
for(int j=0;j<=y;j++)
{
if(j>=b[i])
d[i][j]=d[i-1][j]>(d[i-1][j-b[i]]+a[i])?d[i-1][j]:(d[i-1][j-b[i]]+a[i]);
else
d[i][j]=d[i-1][j];
}
}
cout<<d[x][y]<<endl;
}
return 0;
}