题目描述
如果 背包重量为9,现在有3个物品,其重量、价值、和性价比分别为
1:(3,4,4/3) 2:(4,5,5/4) 3:(5,6,6/5)
求解背包能够装入的最大价值。
算法说明
贪心算法不一定能够得出 0-1 背包的最优解
动态规划可以得出 0-1 背包的最优解
代码实现
#include <iostream>
using namespace std;
int max(int a, int b) {
return a > b ? a : b;
}
// 对商品按照性价比排序
void Quick_sort_value(int weight[], int value[], double w_v[], int left, int right) {
if (left < right) {
int i = left;
int j = right;
double x = w_v[i];
int x_w = weight[i];
int x_v = value[i];
while (i < j) {
while (i<j && w_v[j] < x)
{
j--;
}
if (i < j) {
w_v[i] = w_v[j];
weight[i] = weight[j];
value[i++] = weight[j];
}
while (i < j && w_v[i] > x)
{
i++;
}
if (i < j) {
w_v[j] = w_v[i];
weight[j] = weight[i];
value[j--] = weight[i];
}
}
if (i == j) {
w_v[i] = x;
weight[i] = x_w;
value[i] = x_v;
}
Quick_sort_value(weight, value, w_v, left, i - 1);
Quick_sort_value(weight, value, w_v, i + 1, right);
}
}
/*
* 贪心算法只适合求解小数背包问题,即可以将物品分割的背包问题。
* 例子:如背包重量为9,现在有3个物品,其重量、价值、和性价比分别为
* 1:(3,4,4/3) 2:(4,5,5/4) 3:(5,6,6/5)
* 可以将物品分割成部分。
*/
double greed_Value_decimal(int weight[], int value[],double w_v[], int left, int right,int bagweight) {
// 根据性价比对物品排序。
Quick_sort_value(weight, value, w_v, left, right);
int sum_weight = 0;
double sum_value = 0;
for (int i = left; i <= right; i++) {
sum_weight += weight[i];
if (sum_weight <= bagweight) {
sum_value += value[i];
}
else {
double v = (w_v[i]) * (bagweight - sum_weight + weight[i]);
sum_value = v + sum_value;
break;
}
}
return sum_value;
}
/*
* 贪心算法求解0-1背包问题时,不一定得出最优解。
*
* 例子:如背包重量为9,现在有3个物品,其重量、价值、和性价比分别为
* 1:(3,4,4/3) 2:(4,5,5/4) 3:(5,6,6/5)
*/
int greed_Value(int weight[], int value[], double w_v[], int left, int right, int bagweight) {
// 根据性价比对物品排序。
//Quick_sort_value(weight, value, w_v, left, right);
int sum_weight = 0;
int sum_value = 0;
for (int i = left; i <= right; i++) {
sum_weight += weight[i];
if (sum_weight <= bagweight) {
sum_value += value[i];
}
else {
break;
}
}
return sum_value;
}
/*
* 动态规划算法求解0-1背包问题时,可以得出最优解。
*
* 例子:如背包重量为9,现在有3个物品,其重量、价值、和性价比分别为
* 1:(3,4,4/3) 2:(4,5,5/4) 3:(5,6,6/5)
*/
int dynamic_planning(int weight[], int value[], int n, int bagweight) {
int* dp = new int[bagweight + 1];
// 初始化dp数组
for (int j = 0; j <= bagweight; j++) {
if (weight[0] < j) {
dp[j] = value[0];
}
else {
dp[j] = 0;
}
}
// 动态规划找最大价值
for (int i = 1; i < n; i++) {
for (int j = bagweight; j >= 0; j--) {
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
return dp[bagweight];
}
int main()
{
int weight[] = { 3,4,5 };
int value[] = { 4, 5, 6 };
double w_v[] = { (double)4 / 3, (double)5 / 4 ,(double) 6 / 5 };
int bagweight = 9;
// 贪心算法求解小数背包为题
double maxvalue = greed_Value_decimal(weight, value, w_v, 0, 2, bagweight);
cout.precision(6);
cout << "贪心算法求解小数背包: " << maxvalue << endl << endl;
// 贪心算法求解 0-1 背包为题
maxvalue = greed_Value(weight, value, w_v, 0, 2, bagweight);
cout << "贪心算法求解 0-1 背包: " << maxvalue << endl << endl;
// 动态规划求解 0-1 背包为题
maxvalue = dynamic_planning(weight, value, 3, bagweight);
cout << "动态规划求解 0-1 背包: " << maxvalue << endl << endl;
return 0;
}
程序运行结果