杭电acm
Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 87013 Accepted Submission(s): 35933
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
借着这个题学习一下01背包吧,学贪心不久,算这种背包问题一直用算价值比较,然后加到空间占满来着,结果这个题交了N遍都没过,无奈只能找别的方法了,看了一下这位大佬才知道可以这么用,表格可以说让人看起来很清楚了,拷到这大家看一下吧。
https://blog.csdn.net/shellhard/article/details/62083266
简单说一下吧,核心代码就是下面这一段
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++) //从0开始意味着重量为0也可以计算
{
if(j>=w[i])
{
s[i][j]=max(s[i-1][j],s[i-1][j-w[i]]+v[i]);
// 此时的值是[i-1][j-w[i]]+v[i] 和 [i-1][j]比较
}
else
s[i][j]=s[i-1][j];
}
}
左边代表骨骼的数量,从0到5,总体积为10,从1排到10,
我们定义一个二维数组m[ i ][ j ] i表示第i个骨骼,j表示背包容量为j;
用0-1背包的问题来求解,就是要得到每一步的最优解,此时第i个物品面临选择,首先我们要看容量是否大于它的重量,
即 j > w[ i ]
如果大于,我们可以选择拿或不拿
1:拿,那么就必须要占用当前背包的空间。即用当前背包总容量 j - w[ i ],再占用1个物品空间,所以i-1,此时的总价值就是m [ i-1 ] [ j-w[ i ] ] 的解 + 当前的价值v[ i ] ,得到的就是放入当前物品得到的最优解。
2:不拿,那么就还是上一步的解,m[ i-1 ][ j ]
下面是AC代码:
//#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
int w[1003]; //体积
int v[1003]; //价值
int s[1003][1003];
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
memset(s,0,sizeof(s));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v[i]; //每个骨骼的价值
}
for(int i=1;i<=n;i++)
{
cin>>w[i]; //每个骨骼的体积
}
//0-1背包
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++) //从0开始意味着重量为0也可以计算
{
if(j>=w[i])
{
s[i][j]=max(s[i-1][j],s[i-1][j-w[i]]+v[i]); // 此时的值是[i-1][j-w[i]]+v[i] 和 [i-1][j]比较
}
else
s[i][j]=s[i-1][j];
}
}
cout<<s[n][m]<<endl;
}
return 0;
}
讲起来倒是容易理解,写到博客才感觉好多东西是写不出来的,加油吧