01 背包问题

下标 0 1 2 3 4
价值 5 10 3 6 3
重量 2 5 1 4 3
物品 \ 背包容量 0 1 2 3 4 5 6
0 0 0 0 0 0 0 0
1 0 0 5 5 5 5 5
2 0 0 5 5 5 10 10
3 0 3 5 8 8 10 13
4 0 3 5 8 8 10 13
5 0 3 5 8 8 10 13

说明:

思路

往dp表格中计算填写值。

最后的结果在 dp[5][6],即最大价值为 13

cpp代码实现

#include <iostream>
#include <algorithm>
#include <vector>
int knapsack(int capacity, const std::vector<int> &weights, const std::vector<int> &values)
{
    int n = weights.size();
    // 使用 std::vector 创建二维 DP 表,初始化为 0
    std::vector<std::vector<int>> dp(n + 1, std::vector<int>(capacity + 1, 0));

    // 填充 DP 表
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= capacity; ++j)
        {
            if (weights[i - 1] <= j)
            {
                dp[i][j] = std::max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);
            }
            else
            {
                dp[i][j] = dp[i - 1][j];
            }
            std::cout << dp[i][j] << " ";
        }
        std::cout << std::endl;
    }

    // 返回 DP 表中最后一个格子的值,即为最大价值
    return dp[n][capacity];
}

int main()
{
    std::vector<int> values = {5, 10, 3, 6, 3};
    std::vector<int> weights = {2, 5, 1, 4, 3};
    int capacity = 6;

    int max_value = knapsack(capacity, weights, values);
    std::cout << "Maximum value in knapsack = " << max_value << std::endl;

    return 0;
}

cpp空间优化


int knapsack_new(int capacity, const std::vector<int> &weights, const std::vector<int> &values)
{
    int n = weights.size();
    // 创建两个一维 DP 数组
    std::vector<int> dp_prev(capacity + 1, 0);
    std::vector<int> dp_curr(capacity + 1, 0);

    // 填充 DP 表
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= capacity; ++j)
        {
            if (weights[i - 1] <= j)
            {
                dp_curr[j] = std::max(dp_prev[j], dp_prev[j - weights[i - 1]] + values[i - 1]);
            }
            else
            {
                dp_curr[j] = dp_prev[j];
            }
            std::cout << dp_curr[j] << " ";
        }
        std::cout << std::endl;
        // 更新 dp_prev 为 dp_curr 的值
        std::swap(dp_prev, dp_curr);
    }

    // 返回 DP 表中最后一个格子的值,即为最大价值
    return dp_prev[capacity];
}