一. 01背包问题
01背包问题是经典的动态规划问题,适合用动态规划求解。问题描述为:给定一个容量为W的背包和n个物品,每个物品有重量和价值,目标是选择物品以最大化背包中的总价值,同时不超过容量W。
问题定义:
- 输入:
- W:背包容量
- weights:物品重量数组
- values:物品价值数组
- 输出:
- 最大价值总和,且装入背包的物品总重量不超过W。
动态规划思路:
- 状态定义:dp[i][j]表示前i个物品在容量为j时的最大价值。
- 状态转移:
- 不选择第i个物品:dp[i][j] = dp[i-1][j]
- 选择第i个物品(前提是重量不超过j):dp[i][j] = dp[i-1][j-weights[i-1]] + values[i-1]
综合:
dp[i][j] = {
dp[i-1][j], 如果 weights[i-1] > j
max(dp[i-1][j], dp[i-1][j-weights[i-1]] + values[i-1]), 否则
}
- 初始化:dp[0][j] = 0(无物品时最大价值为0),dp[i][0] = 0(容量为0时最大价值也为0)。
C++ 示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int knapsack(int W, const vector<int>& weights, const vector<int>& values) {
int n = weights.size();
vector<vector<int>> dp(n + 1, vector<int>(W + 1, 0));
for (int i = 1; i