01背包c++
时间: 2025-06-11 14:33:56 浏览: 12
### 0-1背包问题的C++实现
在解决0-1背包问题时,动态规划是一种非常有效的算法。以下是基于引用[^1]、[^2]和[^3]的详细解释与代码实现。
#### 动态规划的核心思想
动态规划通过构建一个二维数组 `dp[i][j]` 来记录前 `i` 个物品放入容量为 `j` 的背包中的最大价值。状态转移方程如下:
```cpp
dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]] + w[i]);
```
其中:
- `dp[i-1][j]` 表示不选择第 `i` 个物品。
- `dp[i-1][j-v[i]] + w[i]` 表示选择第 `i` 个物品,前提是背包容量足够(即 `j >= v[i]`)。
为了优化空间复杂度,可以将二维数组压缩为一维数组。此时,第二层循环需要从后往前遍历,以确保每个物品只被使用一次。
#### C++代码实现
以下是一个完整的0-1背包问题的C++实现:
```cpp
#include <iostream>
#include <vector>
using namespace std;
int knapsack(int N, int W, vector<int>& weights, vector<int>& values) {
vector<int> dp(W + 1, 0); // 初始化dp数组,大小为W+1,默认值为0
for (int i = 1; i <= N; i++) { // 遍历每个物品
for (int j = W; j >= weights[i - 1]; j--) { // 倒序遍历背包容量
dp[j] = max(dp[j], dp[j - weights[i - 1]] + values[i - 1]); // 状态转移方程
}
}
return dp[W]; // 返回容量为W时的最大价值
}
int main() {
int N, W; // 物品数量和背包容量
cin >> N >> W;
vector<int> weights(N), values(N);
for (int i = 0; i < N; i++) {
cin >> weights[i] >> values[i]; // 输入每个物品的重量和价值
}
cout << knapsack(N, W, weights, values) << endl; // 输出结果
return 0;
}
```
#### 关键点解析
1. **倒序遍历的原因**:
在一维数组优化中,如果正序遍历,当前物品会被重复使用多次,从而变成完全背包问题。为了避免这种情况,必须从后往前遍历背包容量。
2. **时间复杂度**:
外层循环遍历所有物品,内层循环遍历背包容量,因此总的时间复杂度为 \(O(N \times W)\),其中 \(N\) 是物品数量,\(W\) 是背包容量[^2]。
3. **空间复杂度**:
使用一维数组代替二维数组,将空间复杂度从 \(O(N \times W)\) 降低到 \(O(W)\)[^1]。
---
阅读全文
相关推荐













