当前位置:首页 > 牛客 > 牛客226516题解:动态规划解决完全背包问题(附代码解析)

牛客226516题解:动态规划解决完全背包问题(附代码解析)

5个月前 (06-28)

牛客226516题解:动态规划解决完全背包问题(附代码解析) 动态规划 背包问题 01背包问题 完全背包问题 牛客 第1张

一、题目解读

牛客226516题要求解决两类完全背包问题:普通完全背包(求最大价值)与恰好装满的完全背包(判断是否存在方案)。题目给定n个物品,每个物品有体积v和价值w,背包容量为V。需分别计算两种情况下背包能容纳的最大价值或是否存在恰好装满的方案。

二、解题思路

核心采用动态规划

问题1(普通完全背包)允许物品重复选取,使用dp数组表示容量j时的最大价值,状态转移方程为dp[j] = max(dp[j], dp[j-v[i]] + w[i]),通过遍历物品和容量构建最优解。

问题2(恰好装满)需初始化dp[0]=0(表示空背包合法),其余状态置-1,仅当dp[j-v[i]]合法时才更新dp[j],最终判断dp[V]是否非-1确定答案。

三、解题步骤

1. 输入物品数量n、背包容量V,及物品体积v和价值w数组。

2. 问题1:初始化dp1全0,外层循环物品,内层正序遍历容量,按动态规划方程更新dp1。

3. 问题2:初始化dp2,仅dp2[0]=0,其余为-1;遍历物品后正序更新容量,依赖合法前置状态计算新值。

4. 输出dp1[V]和问题2的特殊判断结果。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void solve() {
    int n, V;
    cin >> n >> V;   // 输入物品数量n和背包容量V
    vector<int> v(n), w(n); // 物品体积和价值数组
    for (int i = 0; i < n; ++i) {
        cin >> v[i] >> w[i];
    }

    // 问题1:普通完全背包
    vector<int> dp1(V + 1, 0); // dp1[j]表示容量j时的最大价值
    for (int i = 0; i < n; ++i) {
        for (int j = v[i]; j <= V; ++j) { // 正序遍历容量(可重复选)
            dp1[j] = max(dp1[j], dp1[j - v[i]] + w[i]);
        }
    }
    cout << dp1[V] << endl; // 输出最大价值

    // 问题2:恰好装满的完全背包
    vector<int> dp2(V + 1, -1); // -1表示未计算,-1的更新结果仍为-1
    dp2[0] = 0; // 空背包合法
    for (int i = 0; i < n; ++i) {
        for (int j = v[i]; j <= V; ++j) {
            if (dp2[j - v[i]]!= -1) { // 仅当前置状态合法时才更新
                dp2[j] = max(dp2[j], dp2[j - v[i]] + w[i]);
            }
        }
    }
    cout << (dp2[V] == -1? 0 : dp2[V]) << endl; // 若dp2[V]为-1则无解,否则输出价值
}

int main() {
    solve();
    return 0;
}

五、总结

本题通过动态规划巧妙解决两类完全背包问题。关键差异在于初始化和状态转移条件:普通背包允许重复选取,初始化全0;恰好装满需空背包合法,依赖合法前置状态更新。代码简洁高效,体现了动态规划在背包问题中的经典应用。

原创内容 转载请注明出处

分享给朋友:

相关文章

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

题目重解:数字三角形是一个经典的动态规划问题,给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们需要找到一条路径,使得路径上经过的数字总和最大。这个问题可以很...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

牛客25461题解析:花园喷泉距离优化算法(动态规划+后缀数组解法)

牛客25461题解析:花园喷泉距离优化算法(动态规划+后缀数组解法)

一、题目解读牛客25461题要求计算一个花园中n朵花到两个喷泉的最小距离平方和。用户需输入喷泉坐标(x1,y1)和(x2,y2),以及n朵花的坐标(x,y),通过合理分配每朵花到两个喷泉的距离,使总距...

2022 CSP-J 上升点序(洛谷P8816)解题报告:动态规划求解最长上升序列

2022 CSP-J 上升点序(洛谷P8816)解题报告:动态规划求解最长上升序列

一、题目解读2022年CSP-J题目“上升点序”(洛谷P8816)要求给定一个平面点集,每个点的坐标(x,y)均为整数。题目需要构造一个最长的上升序列,序列中相邻点的坐标满足x和y均严格递增。允许使用...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。