动态规划06-01背包问题理论(Java)

本文详细阐述了0-1背包问题的理论基础,包括动态规划的五个步骤,递推公式,以及如何通过Java代码实现。重点强调了内层循环倒序遍历的重要性,以避免重复计算并确保结果准确性。
摘要由CSDN通过智能技术生成

06.0-1背包问题理论基础

  • 题目描述

有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

  • 题目分析
1. 背包问题是一类典型的动态规划题目,它是想在有限的背包容量中
装入不同重量,不同价值的物品,使得最终在没有超过背包容量的
前提下,使得背包的价值取得最大值。
2. 0-1背包问题是指:在每个物品均只有1个的情况下进行选择,每个
物品可放可不放,存在这样的两种状态。

动态规划五部曲

1. 确定dp数组以及下标的含义
设置二维数组dp[i][j]:表示选取物品编号为0-i的物品,书包容量为j的情况下,背包的最大价值
dp[i][j]
i:物品0~物品i  j:背包的容量为j
        容量0   容量1   容量2   容量3   容量4
编号0
编号0-1
编号0-2
编号0-3
2. 确定递推公式
已知物品的重量为weight[i],物品的价值为value[i]
不放物品i的最大重量为:dp[i-1][j]
放置物品i的最大重量为:dp[i-1][j-weight[i]] + value[i]
则在背包容量为j的情况下,背包的最大价值为:
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])
3. dp数组如何初始化
当j=0时,由于背包容量为0,所以此列的最大价值均为0
当i=0是,背包只能装物品0,当背包容量>=物品0重量时可以初始化为物品0的价值
4. 确定遍历顺序
这里选择先遍历物品,再遍历背包
5. 举例推导dp数组
  • Java代码关键步骤
for (int i = 1; i < weight.size(); i++) { // 遍历物品
  for (int j = 0; j <= bagweight; j++) { // 遍历背包容量
    if (j < weight[i]) dp[i][j] = dp[i - 1][j];
    else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
            }
        }
  • 0-1背包问题降阶处理

根据上述讨论已经得到了0-1背包问题的递推公式

dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])
不难看出dp[i][j]取决于dp[i-1][j],因此可以将二维数组压缩成一位dp数组,dp[j]表示背包容量为j时的最大价值

压缩后的递推公式为

dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i])

Java核心代码

for (int i = 1; i < items.length; i++) { // 遍历物品
  for (int j = badweight; j > 0; j--) { // 遍历背包容量
    if (j >= item[i]) {
       dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
    } 
    /*
    else dp[j] = dp[j];//可以省略
    */
}

在解决背包问题时,内层循环倒序遍历背包容量是为了避免重复计算。

背包问题具有重叠子问题的性质,即通过不同的选择可能会得到相同的状态。在这种情况下,如果按顺序遍历背包容量,会在计算某个状态时用到尚未更新的状态,从而导致结果不正确。

倒序遍历背包容量可以保证在计算某个状态时,所有可能需要用到的子问题状态都已经计算完成。这样可以避免重复计算,确保得到的结果是正确的。

总而言之,dp[j]的状态取决于前面的状态,若从前往后遍历会导致大量重复,进而使得结果错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值