当前位置:首页 > 牛客 > 牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

10个月前 (05-21)

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整? 牛客 动态规划 01背包 01背包变体 算法 C++ 状态转移方程 递推 第1张

题目重解

我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0)。这就像旅行前收拾行李箱,既要考虑普通装箱,又要应对航空公司严格的重量限制。

解题思路

代码分为清晰的两阶段:

常规背包处理:初始化dp数组全为0,通过逆序更新保证物品只选一次。状态转移方程dp[j] = max(不选当前物品, 选当前物品)体现经典01背包思想。

必须装满的处理:将dp初始值设为负数(代码中用-10000模拟),仅dp[0]=0。这样只有恰好达到j容量的状态才能被有效转移,最终结果需与0比较避免负值输出。

代码和注释

#include <cstdlib>
#include<iostream>
using namespace std;
int main() {
    // 输入物品数n和背包容量V
    int n, V;
    cin >> n >> V;

    // 动态分配数组存储重量w和价值v
    int* v=new int[n];
    int* w=new int[n];
    for(int i=0;i<n;i++)
        cin>>w[i]>>v[i];

    // 常规01背包处理
    int* dp = new int [V + 1]; 
    for(int i=0;i<=V;i++){
        dp[i]=0; // 初始化:什么都不装时价值为0
    }

    for(int i=1;i<=n;i++){ // 遍历每个物品
        for(int j=V;j>=w[i-1];j--){ // 逆序更新防止重复选取
            dp[j]=max(dp[j], v[i-1]+dp[j-w[i-1]]); // 经典状态转移
        }
    }
    cout<<dp[V]<<endl; // 输出常规解

    // 必须装满背包的处理
    for(int i=1;i<=V;i++){
        dp[i]=-10000; // -∞初始化表示不可达状态
    }

    for(int i=1;i<=n;i++){
        for(int j=V;j>=w[i-1];j--){
            dp[j]=max(dp[j], v[i-1]+dp[j-w[i-1]]); // 转移方程相同但初始条件不同
        }
    }
    cout<<max(dp[V],0); // 负数时输出0表示无法装满
    return 0;
}


原创内容 转载请注明出处

分享给朋友:

相关文章

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

从零到一掌握背包问题:洛谷P1164题解精讲,附带优化

从零到一掌握背包问题:洛谷P1164题解精讲,附带优化

题目重解:小A带着m元钱来到餐馆,菜单上有n道菜,每道菜都有确定的价格。现在需要计算出刚好花完m元的点菜方案总数。这个问题看似简单,但当菜品数量增多时,暴力枚举就会变得不可行,需要更高效的算法来解决。...

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

题目解读‌斐波那契数列是一个经典的数学问题,在计算机科学中常被用作算法教学的入门案例。这个神奇的数列从0和1开始,后续每个数字都是前两个数字之和。题目要求我们计算第n个斐波那契数,看似简单的问题背后却...

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

一、题目解读小杨买饮料是GESP 2023年六级认证考试中的一道经典动态规划题目,考察学生对背包问题的理解和应用能力。题目描述小杨需要购买n种饮料,每种饮料有特定的体积w和价格v,他要在不超过容量l的...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

发表评论

访客

看不清,换一张

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