leetcode-动态规划-01背包

一、二维数组

1、状态转移方程:

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品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]);

2、初始化

(1)从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。

(2)状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。

dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

那么很明显当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。

当j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。

for (int j = 0 ; j < weight[0]; j++) {
    dp[0][j] = 0;
}
// 正序遍历
for (int j = weight[0]; j <= bagweight; j++) {
    dp[0][j] = value[0];
}

(3)其他下标初始化:

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

dp[1][1] = max(dp[0][1], dp[0][1- weight[i]]    + value[i]) 一定在其左方且上方,

故一定初始化过了,可以设置为任何值,为了方便,现默认初始化为0。

二、一维(滚动数组)

1、一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]

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

2、初始化

(1)dp[0]=0,因为背包容量为0所背的物品的最大价值就是0。

(2)假设物品价值都是大于0的,为了不被初始值覆盖,所以dp数组初始化的时候,都初始为0

3、遍历顺序

倒序遍历

解释1:列表后面的值需要通过与上一层遍历得到的前面的值比较确定

解释2:01背包每个背包都只有一个,这个包放于不放与上一个包的状态有关,而左边的数组是描述上一个包状态的量,右边的数是当前包状态的一个待定,代码里是右边数组的确定需要左边的数,所以在计算出右边的数之前不能破坏左边的数。

解释3:对于二维,我每个新的dp数字的结果,都来源于上面和左边;其实一维也本该是这样,但一维的时候,如果还是从左到右,那么我其实左边的数字已经更新过了(左边已经不是“原来的”左边了!这会造成某些重复计算),即使上面还是原来的上面,得到的数字也是不正确的。而如果我们在背包层(里层)从右到左地遍历,那么左边的元素永远不会因为我前一次的操作被覆盖上新的值,这样可以得到正确的值。

相关推荐

  1. leetcode-动态规划-01背包

    2024-07-10 18:52:04       12 阅读
  2. 动态规划09-完全背包

    2024-07-10 18:52:04       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 18:52:04       5 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 18:52:04       5 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 18:52:04       4 阅读
  4. Python语言-面向对象

    2024-07-10 18:52:04       7 阅读

热门阅读

  1. 软件开发面试题C#,.NET知识点(续)

    2024-07-10 18:52:04       12 阅读
  2. git命令获取当前分支远端分支名

    2024-07-10 18:52:04       12 阅读
  3. oracle查询出表中某几个字段值不唯一的数据

    2024-07-10 18:52:04       12 阅读
  4. Git 常用命令

    2024-07-10 18:52:04       7 阅读
  5. C#规则引擎

    2024-07-10 18:52:04       10 阅读
  6. 深度学习Day-24:ResNeXt-50算法思考

    2024-07-10 18:52:04       10 阅读
  7. 完全背包求具体方案(c++题解)

    2024-07-10 18:52:04       10 阅读
  8. Pull Request

    2024-07-10 18:52:04       10 阅读
  9. stm32使用硬件SPI

    2024-07-10 18:52:04       8 阅读
  10. Elasticsearch7.10集群搭建

    2024-07-10 18:52:04       8 阅读
  11. 串口工具推荐

    2024-07-10 18:52:04       10 阅读