您的位置:首页 > 其它

HDOJ 2602 Bone Collector(0-1背包)

2017-07-03 22:34 316 查看
原题链接

题目描述

题目大意

给定一序列的骨头,每个骨头有它自己的体积(volume)和价值(value),现在给定一个容量为V的袋子,问此袋子能装下的骨头的最大价值是多少?

题目分析

这是一个基本的0-1背包问题。

我们依次遍历每一个骨头,在遍历到第i个骨头时,我们要么选择此骨头,要么不选。因此,可设dp[i][j]表示前i个骨头,背包容量为j的最优值。状态转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]] + w[i]);

基于这个状态方程,我们可以写出相应程序。

不过,0-1背包的dp矩阵可以优化到一维数组。

0-1背包伪代码:

for i = 1 to n  //所有物品
for j = V to v[i]
dp[j] = max(dp[j] , dp[j-v[i]] + w[i]);


在上述伪代码中,我们可以看到:在状态转移的时候,背包容量从大到小,这是为了避免同一个物品被取多次。与之相对的是,处理完全背包的时候,一件物品可以取任意多次,此时我们的背包容量要从小到大进行转移,使得一件物品可以被取多次。

AC代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

int v[1005];
int c[1005];
int dp[1000];

int main() {
int T, N, V;
cin >> T;
while (T--) {
cin >> N >> V;
for (int i = 0; i < N; ++i) {
cin >> v[i];
}
for (int i = 0; i < N; ++i) {
cin >> c[i];
}
memset(dp, 0, sizeof(dp));
for (int i = 0; i < N; ++i) {
for (int j = V; j >= c[i]; j--)
dp[j] = max(dp[j], dp[j-c[i]]+v[i]);
}
cout << dp[V] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDOJ-2602 0-1背包