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

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

7个月前 (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;
}


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

一:重新解读题目泰波那契数列是一个充满数学趣味的递推序列:从第3项开始,每个数均为前三个数的和(即Tₙ₊₃ = Tₙ + Tₙ₊₁ + Tₙ₊₂)。当给定整数n时,需要高效计算出第n项的值。面对此类递...

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

一、题目解读题目要求在一个n×m的网格中,从左上角到右下角选择一条路径,路径上的数字可重复取用,求取数之和的最大值。路径限制为仅能向右或向下移动。需注意路径的灵活性与重复取数的可能性,传统单向动态规划...

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

内容简介本文详细解析了力扣第44题"寻找两个正序数组的中位数"的合并排序解法。通过双指针技术合并两个有序数组,然后直接计算合并后数组的中位数。虽然时间复杂度为O(m+n),但这种方...

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

一、题目解读    “生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,...

发表评论

访客

看不清,换一张

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