题目描述
需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。
输入
多个测例,每个测例的输入占三行。第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,第三行n个整数分别是p1到pn。
n 和 c 都等于零标志输入结束。
输出
每个测例的输出占一行,输出一个整数,即最佳装载的总价值。
样例输入
1 2 1 1 2 3 2 2 3 4 0 0
样例输出
1 4
代码实现(二维数组)
#include <iostream>
using namespace std;
/*
* 动态规划 实现0-1背包的 思想:
*
*
* 1. 二位数组实现
* 2. 一维(滚动)数组实现
*/
// 找出两个数中的大值
int max(int a, int b) {
return a > b ? a : b;
}
// 1. 二位数组实现
int maxValue_1(int weight[], int value[],int res[], int n, int c) {
// 动态申请二维数组
int** dp = new int* [n];
for (int i = 0; i < n; i++) {
dp[i] = new int[c+1];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < c+1; j++) {
dp[i][j] = 0;
}
}
// 初始化dp数组
for (int j = 0; j <= c; j++) {
if (j < weight[0]) {
dp[0][j] = 0;
}
else {
dp[0][j] = value[0];
}
}
// 动态规划找到最大价值
for (int i = 1; i < n; i++) {
for (int j = 0; j <= c; j++) {
if (j < weight[i]) {
dp[i][j] = dp[i-1][j];
}
else{
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
}
}
}
// 定义一个数保存最大价值
int max_value = dp[n-1][c];
// 逆向 找出放入背包的物品
for (int i = n-1; i > 0; i--)
{
if (dp[i][c] == dp[i - 1][c])
res[i] = 0;
else
{
res[i] = 1;
c -= dp[i][c];
}
}
res[0] = (dp[0][c] > 0) ? 1 : 0;
// 二位数组空间收回
for (int i = 0; i < n; i++) {
delete[] dp[i];
}
delete[] dp;
return max_value;
}
int main()
{
int n, c;
while (true)
{
cin >> n;
cin >> c;
if (n == 0 || c == 0) {
break;
}
// 输入每个样品的重量
int* weight = new int[n];
for (int i = 0; i < n; i++) {
cin >> weight[i];
}
// 输入每个物品的价值
int* value = new int[n];
for (int i = 0; i < n; i++) {
cin >> value[i];
}
// 第一一个显示哪个物品被放入的数组。0表示没有放入,1表示放入
int* res = new int[n];
int maxvalue = maxValue_1(weight, value, res,n, c);
cout << maxvalue << endl;
delete[] weight;
delete[] value;
}
}
代码实现(一维滚动数组)
#include <iostream>
using namespace std;
/*
* 动态规划 实现0-1背包的 思想:
*
*
* 1. 二位数组实现
* 2. 一维(滚动)数组实现
*/
// 找出两个数中的大值
int max(int a, int b) {
return a > b ? a : b;
}
// 2. 一维(滚动)数组实现
int maxValue_2(int weight[], int value[], int n, int c) {
// 动态申请一维数组
int* dp = new int [c+1];
for (int j = 0; j < c + 1; j++) {
dp[j] = 0;
}
// 初始化dp数组
for (int j = 0; j <= c; j++) {
if (j < weight[0]) {
dp[j] = 0;
}
else {
dp[j] = value[0];
}
}
// 动态规划找到最大价值
for (int i = 1; i < n; i++) {
for (int j = c; j >= weight[i]; j--) {
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
// 定义一个数保存最大价值
int max_value = dp[c];
// 一维数组空间收回
delete[] dp;
return max_value;
}
int main()
{
int n, c;
while (true)
{
cin >> n;
cin >> c;
if (n == 0 || c == 0) {
break;
}
// 输入每个样品的重量
int* weight = new int[n];
for (int i = 0; i < n; i++) {
cin >> weight[i];
}
// 输入每个物品的价值
int* value = new int[n];
for (int i = 0; i < n; i++) {
cin >> value[i];
}
// 第一一个显示哪个物品被放入的数组。0表示没有放入,1表示放入
int* res = new int[n];
int maxvalue = maxValue_2(weight, value, n, c);
cout << maxvalue << endl;
delete[] weight;
delete[] value;
}
}