杭电2602(01背包问题)——第一次做背包问题的理解

Bone Collector


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
 
分析:题的大意就是一个家伙喜欢收集骨头,让你求一下在容器有限的情况下,装的骨头的最大价值;
       例如给的输入数据是:
1//表示测试数据有一组
5 10//5表示有有五个骨头,10表示容器容量为10
1 2 3 4 5//表示五个骨头每个的价值
5 4 3 2 1//表示五个骨头的体积
  输出为
14//装价值为5,4,3,2,的骨头价值最大。
01背包算法:
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 9 9
5 5 5 9 9 9 12 12 12 12 14
上表的我理解的意思就是:(第一行是j的值变化,第一列是i的值变化)
  骨头编号按价值从1—5编号i=1,2 3,4,5.   j时容量从1到10变化
 i=0时全是0;
  当i=1时,j从0到10变化,看能装的最大价值,可见当容器为5时,能装下此时价值i=1,体积为5的骨头,
   当j=6,7,8,9,10时只能装上5,要问为6时为什么不要装容价值为1和容量为1的i=5的骨头呢?是因为此时
还没有排到她,此表是从容量为1,1号骨头开始往后排的,是此时此空间内所能放骨头的最大值。
然后在逐渐加大i和j的值,再在所增加的空间上最大的价值,怎样保证最大呢?就是在所增加的空间上先放一个最大价值的骨头,在求出剩余的空间,从前面空间内找到剩余空间上放的价值,加到一起就是最大的价值(因为剩余空间上放的也是最大价值!所以在右下角的14就是最大价值!当然也有一些情况是如果加上最大价值的那个所得价值不是最大的,那就比较一下,是不是最大的,怎样比较呢?就是记下每一次增加的最大值,与再增加的比较就行了!
代码如下:
#include<iostream>
using namespace std;
int a[1005],b[1005];
int d[1005][1005];
int main()
{
int n;
cin>>n;
while(n--)
{     int x,y,i,j;
cin>>x>>y;
for(i=1;i<=x;i++)
cin>>a[i];
for(i=1;i<=x;i++)
cin>>b[i];
         for(i=1;i<=x;i++)
for(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;
}

























原文地址:https://www.cnblogs.com/javawebsoa/p/3201314.html