编写C++程序实现: 1、<验证> 输入背包容量,物品数量、价值及重量,利用动态规划法解决0-1背包问题,要求输出装入物品的对应指示向量,并分析该算法性能。 2、<探索> 当背包允许物品部分装入时,重新设计动态规划策略,满足背包承载最大时价值最高,输出指示向量,并与问题1结果相比较,同时分析算法性能差异。
时间: 2024-03-03 20:50:34 浏览: 72
LeetCode从简单到困难-每日一题-动态规划法求解0-1背包
好的,我理解了你的要求,我将分别回答你的两个问题。
1. C++程序实现0-1背包问题的动态规划算法
0-1背包问题是一种经典的优化问题,其思想是在给定的物品中选择一些物品,使得它们的总价值最大,同时不超过背包的容量限制。这个问题可以通过动态规划求解,具体实现如下:
```cpp
#include <iostream>
#include <vector>
using namespace std;
// 0-1背包问题的动态规划算法
void knapsack01(int C, vector<int> w, vector<int> v)
{
int n = w.size();
vector<vector<int>> dp(n+1, vector<int>(C+1, 0));
vector<int> x(n, 0);
// 动态规划过程
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= C; j++) {
if (w[i-1] <= j && dp[i-1][j-w[i-1]] + v[i-1] > dp[i-1][j]) {
dp[i][j] = dp[i-1][j-w[i-1]] + v[i-1];
x[i-1] = 1;
}
else {
dp[i][j] = dp[i-1][j];
}
}
}
// 输出结果
cout << "物品选择情况:" << endl;
for (int i = 0; i < n; i++) {
cout << x[i] << " ";
}
cout << endl << "最大总价值为:" << dp[n][C] << endl;
}
int main()
{
// 输入数据
int C, n;
cout << "请输入背包容量C和物品数量n:";
cin >> C >> n;
vector<int> w(n), v(n);
cout << "请输入每个物品的重量和价值:";
for (int i = 0; i < n; i++) {
cin >> w[i] >> v[i];
}
// 调用函数
knapsack01(C, w, v);
return 0;
}
```
上述代码通过二维数组 `dp` 记录了每个子问题的最优解,同时使用一维数组 `x` 记录了选择的物品情况。该算法的时间复杂度为 $O(nC)$,空间复杂度为 $O(nC)$。
2. C++程序实现可以部分装入的背包问题
在部分装入的背包问题中,物品可以被分割为任意大小的部分,因此一个物品可以选择装入一部分,而不必全部装入或全部不装入。这个问题可以通过动态规划求解,具体实现如下:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 01背包问题的动态规划算法
void knapsack_fraction(int C, vector<int> w, vector<int> v)
{
int n = w.size();
vector<pair<double,int>> vw(n);
for (int i = 0; i < n; ++i) {
vw[i] = make_pair((double)v[i]/w[i], i);
}
sort(vw.rbegin(), vw.rend());
vector<double> x(n, 0);
double value = 0;
for (int i = 0; i < n; ++i) {
if (w[vw[i].second] <= C) {
x[vw[i].second] = 1;
value += v[vw[i].second];
C -= w[vw[i].second];
}
else {
x[vw[i].second] = (double)C/w[vw[i].second];
value += x[vw[i].second] * v[vw[i].second];
C = 0;
break;
}
}
// 输出结果
cout << "物品选择情况:" << endl;
for (int i = 0; i < n; i++) {
cout << x[i] << " ";
}
cout << endl << "最大总价值为:" << value << endl;
}
int main()
{
// 输入数据
int C, n;
cout << "请输入背包容量C和物品数量n:";
cin >> C >> n;
vector<int> w(n), v(n);
cout << "请输入每个物品的重量和价值:";
for (int i = 0; i < n; i++) {
cin >> w[i] >> v[i];
}
// 调用函数
knapsack_fraction(C, w, v);
return 0;
}
```
上述代码中,我们首先计算每个物品的单位价值,然后对物品按照单位价值从大到小排序,依次选择单位价值最大的物品直到背包容量不足为止。如果最后还有剩余的背包容量,则将其全部分配给单位价值最大的物品。这个算法的时间复杂度为 $O(n\log n)$。
总结:部分装入背包问题的算法在一定程度上放宽了背包问题的限制,可以得到更优的结果。但是,由于需要排序,其时间复杂度较高,因此在实际应用中需要根据具体情况选择使用哪种算法。
阅读全文