小工具知识网

当前位置: 首页 > 行业知识 > Leetcoder Day37| 动态规划part04 背包问题

行业知识

Leetcoder Day37| 动态规划part04 背包问题

2026-11-14 21:56:00 来源:互联网转载

01背包理论基础

面试���握01背包,完全背包和重背包就够用了。

背包问题的理论基础重中之重是01背包,一定要理解透!

01 背包

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

每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是o(2^n),这里的n表示物品数量。

所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!

举例:背包最大重量为4。

物品为:

重量价值
物品0115
物品1320
物品2430

问背包能背的物品最大价值是多少?

以下讲解和图示中出现的数字都是以这个例子为例。

二维数组01背包

依然动规五部曲分析一波。

1. 确定dp数组以及下标的含义

对于背包问题,有一种写法, 是使用二维数组,即dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。要时刻记着这个dp数组的含义,下面的一些步骤都围绕这dp数组的含义进行的。

2.  确定递推公式

有两个方向可以推出来dp[i][j],

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量或背包剩余重量小于i的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)
  • 放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。

    所以dp[i][j]= max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

    3. dp数组如何初始化

    关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱。

    首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。i是由i-1推出来的,所以i为0的时候就一定要初始化。刚才讨论过j=0的情况,那么i=0时,dp[0][j],即:存放编号0的物品时,各个容量的背包所能存放的最大价值。因此 j =weight[0],dp[0][j]的值为value[0]。

    dp[0][j] 和 dp[i][0] 初始化以后,其他位置都会从i-1或者j-weight[i]而来,因此都会被不断地覆盖,所以初始化为0即可。

    4. 确定遍历顺序

    在如下图中,可以看出,有两个遍历的维度:物品与背包重量,从哪个方向遍历都可以,因此我们就从物品开始遍历。

    public static void backValue(int[]value, int[] weight, int bagWeight){        int num=value.length;        int[][]dp=new int[num][bagWeight+1];        for(int j=weight[0];j

上一篇:App源码封装全揭秘,高效开发的一站式解决方案!

下一篇:服务器上的小爱心怎么取消?