动态规划(dp)
背包问题
0-1背包
0-1背包问题是一种组合优化的 NP
完全问题:有 N
个物品和容量为 W
的背包,每个物品都有自己的体积 w
和价值 v
,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0
个或 1
个,则问题称为 0-1
背包问题;如果不限定每种物品的数量,则问题称为无界背包问题或完全背包问题。
解决办法:
用动态规划来解决背包问题。以 0-1
背包问题为例。我们可以定义一个二维数组 dp
存储最大价值,其中 dp[i][j]
表示前 i 件物品体积不超过 j
的情况下能达到的最大价值。在我们遍历到第 i
件物品时,在当前背包总容量为j
的情况下,如果我们不将物品 i
放入背包,那么 dp[i][j]= dp[i-1][j]
,即前 i
个物品的最大价值等于只取前 i-1
个物品时的最大价值;如果我们将物品 i
放入背包,假设第 i
件物品体积为 w
,价值为 v
,那么我们得到 dp[i][j] = dp[i-1][j-w] + v
。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 O(NW)
。
代码:
int knapsack(vector<int> weights, vector<int> values, int N, int W)
{
vector<vector<int>> dp(N + 1, vector<int>(W + 1, 0)); //dp空间二维vector
for (int i = 1; i <= N; ++i) //遍历N件物品
{
int w = weights[i-1], v = values[i-1]; //初始化从0
for (int j = 1; j