您的位置:首页 > 其它

hdu 2602 Bone Collector (0 1背包入门)

2017-05-18 10:40 483 查看
本题链接:点击打开链接

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 60878    Accepted Submission(s): 25379


[align=left]Problem Description[/align]
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 ?



 

[align=left]Input[/align]
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.
 

[align=left]Output[/align]
One integer per line representing the maximum of the total value (this number will be less than 231).
 

[align=left]Sample Input[/align]

1
5 10
1 2 3 4 5
5 4 3 2 1

 

[align=left]Sample Output[/align]

14

 

[align=left]Author[/align]
Teddy
 

[align=left]Source[/align]
HDU 1st “Vegetable-Birds Cup” Programming Open Contest

 

[align=left]Recommend[/align]
lcy   |   We have carefully selected several similar problems for you:  1203 2159 2955 1171 2844 
 
本题题意:有一个喜欢收集骨头的人,他有一个容量为v的包,现在有n个骨头,每个骨头的价值和体积都不同,现在需要计算他的包可以装的骨头的最大价值是多少?

先输入一个数t,表示有t组测试数据,然后输入骨头数n和背包容量v,接下来第一行为各个骨头的价值,第二行为各个骨头的体积。

解题思路:直接是01背包的裸体,除开输入,就是直接的模板应用。背包也属于动态规划的一种,所以也有动态转移方程。这个题有二维动态数组的解法,也有一维的数组解法,只不过一维的解法不太好理解,也不太好说,关于背包问题的详细解题思路,大家还是看网上大神的《背包九讲》吧。

01背包的特点是:每件物品就一个,可以选择拿与不拿。提醒一下就是背包问题与贪心问题很像,但就是不能用贪心方法做,否则就错了。这个题还有一个坑点就是有体积为0的测试数据。

01背包的状态状态方程式为:

dp[i][j]=max{dp[i-1][j],dp[i-1][j-c[i]]+w[i]}

这个方程的意思就是现在就是将第i件物品放入背包中,这一件物品的体积为c[i],价值为w[i],

因此dp[i-1][j]代表的就是不将这件物品放入背包,

而dp[i-1][j-c[i]]+w[i]则是代表将第i件放入背包之后的总价值,比较这两者的价值,得出最大的价值存入现在的背包之中。

代码实现为:

for(int i=1; i<=n; i++)
for(int j=0; j<=v; j++)
{
if(c[i]<=j)
dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
else
dp[i][j]=dp[i-1][j];
}
本题代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[1001][1001]; //非得定义为全局变量才行,不然就不能运行,我也不知道为什么
int maxx(int a,int b)
{
return a>b?a:b;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,v;
int c[1001],w[1001];
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&v);
for(int i=1; i<=n; i++)
scanf("%d",&w[i]);
for(int i=1; i<=n; i++)
scanf("%d",&c[i]);
for(int i=1;i<=n;i++)
for(int j=0; j<=v; j++) //从0开始,听说本题有体积为0的数据
{
if(c[i]<=j)
dp[i][j]=maxx(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
else
dp[i][j]=dp[i-1][j];
}
printf("%d\n",dp
[v]);
}
return 0;
}


然后这题还有一维的解法。不详说了,大家自己理解,前面我已经说了,也不好去解释。

状态转移方程式为:dp[j]=maxx(dp[j],dp[j-volume[i]]+value[i])

代码实现为:

for(int i=1; i<=n; i++)
{
for(int j=v; j>=volume[i]; j--)
dp[j]=maxx(dp[j],dp[j-volume[i]]+value[i]);
}

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int maxx(int a,int b)
{
return a>b?a:b;
}
int main()
{
int t;
int dp[1001];
scanf("%d",&t);
while(t--)
{
int n,v;
int value[1001],volume[1001];
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&v);
for(int i=1; i<=n; i++)
scanf("%d",&value[i]);
for(int i=1; i<=n; i++)
scanf("%d",&volume[i]);
for(int i=0; i<n; i++)
{
for(int j=v; j>=volume[i]; j--)
dp[j]=maxx(dp[j],dp[j-volume[i]]+value[i]);
}
printf("%d\n",dp[v]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息