题解:学而思编程 超大容量背包

【题目来源】

学而思编程:超大容量背包

【题目描述】

\(n\) 个物品,编号从 \(1\)\(n\),每个物品有一个重量 \(w_i\) 和价值 \(v_i\)

Taro有一个背包,容量为 \(W\),他想要挑选一些物品装到背包里面,要求选择的物品重量和不能超过 \(W\)

Taro想知道他能获得的最大价值是多少?

【输入】

第一行两个整数 \(n(1≤n≤100)\)\(W(1≤W≤10^9)\)

接下来 \(n\) 行,每行两个整数 \(w_i(1≤w_i≤W≤10^9)\)\(v_i(1≤v_i≤10^3)\),表示第 \(i\) 个物品的重量和价值。

【输出】

输出一行,包含一个整数,表示Taro能获得的最大价值。

【输入样例】

3 8
3 30
4 50
5 60

【输出样例】

90

【核心思想】

  1. 问题分析:给定 \(n\) 个物品(重量 \(w_i\),价值 \(v_i\))和背包容量 \(W\)\(W \leq 10^9\)),求在重量不超过 \(W\) 的情况下能获得的最大价值。由于 \(W\) 很大(\(10^9\)),无法使用常规的以重量为维度的DP。但价值 \(v_i \leq 10^3\)\(n \leq 100\),总价值上限为 \(10^5\),可以使用以价值为维度的逆向DP

  2. 算法选择

    • 逆向DPdp[j] 表示获得价值 \(j\) 所需的最小重量
    • 维度转换:将"重量限制下的最大价值"转化为"价值目标下的最小重量"
  3. 关键步骤

    • 初始化dp[0] = 0(获得价值0需要重量0),其余为无穷大
    • 状态转移:逆序遍历价值 \(j\)(从 \(v_i\) 到总价值上限):
      • dp[j] = min(dp[j], dp[j - v[i]] + w[i])(选或不选第 \(i\) 个物品)
    • 统计答案:从高到低遍历价值 \(j\),找到第一个满足 dp[j] <= W\(j\) 即为最大价值
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n \times V_{total})\),其中 \(V_{total} = n \times \max(v_i) \leq 10^5\)
    • 空间复杂度:\(O(V_{total})\),一维数组
  5. 01背包逆向DP的核心思想

    • 维度转换策略:当重量范围大、价值范围小时,将DP维度从重量转换为价值
    • 逆向思维dp[j] 表示获得价值 \(j\) 所需的最小重量,而非传统DP中"重量 \(j\) 下的最大价值"
    • 逆序遍历:01背包的一维优化需要逆序遍历,避免重复选择
    • 结果查找:从高价值向低价值查找,第一个满足重量约束的值即为答案
    • 适用于重量范围极大、价值范围较小的背包问题

【算法标签】

01背包

【代码详解】

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105;
int n, m, w[N], v[N], dp[1000005];  // dp[j]: 获得价值j所需的最小重量

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i] >> v[i];  // 重量, 价值
    }

    memset(dp, 0x3f, sizeof(dp));  // 初始化为无穷大
    dp[0] = 0;  // 价值0需要重量0

    // 0/1背包:求获得价值j的最小重量
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1e5; j >= v[i]; j--)
        {
            dp[j] = min(dp[j], dp[j - v[i]] + w[i]);
        }
    }

    // 从高到低查找不超过重量限制的最大价值
    for (int j = 1e5; j >= 0; j--)
    {
        if (dp[j] <= m)  // 重量不超过m
        {
            cout << j;
            break;
        }
    }
    return 0;
}

【运行结果】

3 8
3 30
4 50
5 60
90
posted @ 2026-06-14 10:48  团爸讲算法  阅读(7)  评论(0)    收藏  举报