0
点赞
收藏
分享

微信扫一扫

LeetCode 1750.删除字符串两端相同字符后的最短长度

伽马星系 2024-11-03 阅读 6

题目

背包问题主要有以下几种分类,对于面试来说掌握0-1背包和完全背包足够,多重背包和分组背包是竞赛级别的题目,面试就无需准备

题目:

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

例子

 背包的最大容量是4

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

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

0-1背包动规五步曲

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

使用二维数组,有两个变量,一个是物品,一个是背包容量

二维数组为dp[i][j]

 i 、j、dp[i][j] 分别表示什么呢?

i 来表示物品、j表示背包容量。

把物品0 放入背包的情况:

背包容量为0,放不下物品0,此时背包里的价值为0。

背包容量为1,可以放下物品0,此时背包里的价值为15.

背包容量为2,依然可以放下物品0 (注意 01背包里物品只有一个),此时背包里的价值为15。

背包容量为3,依然可以放下物品0 (注意 01背包里物品只有一个),此时背包里的价值为15。

背包容量为4,依然可以放下物品0 (注意 01背包里物品只有一个),此时背包里的价值为15。

把物品1放进背包的情况:

背包容量为0,放不下物品1,此时背包里的价值为0。

背包容量为1,放不下物品1,此时背包里的价值为0。

背包容量为2,放不下物品1,此时背包里的价值为0。

背包容量为3,可以放下物品1,此时背包里的价值为20。

背包容量为4,可以放下物品1和物品0,此时背包里的价值为35。

dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

2.确定递推公式

dp[1][4]的状态来举例:

求取 dp[1][4] 有两种情况:

  1. 放物品1
  2. 还是不放物品1

如果不放物品1, 那么背包的价值应该是 dp[0][4] 即 容量为4的背包,只放物品0的情况。

如果放物品1, 那么背包要先留出物品1的容量,目前容量是4,物品1 的容量(就是物品1的重量)为3,此时背包剩下容量为1。

容量为1,只考虑放物品0 的最大价值是 dp[0][1],所以放物品1 的情况 = dp[0][1] + 物品1 的价值

两种情况,分别是放物品1 和 不放物品1,我们要取最大值(毕竟求的是最大价值)

dp[1][4] = max(dp[0][4], dp[0][1] + 物品1 的价值)

以上过程,抽象化如下:

  • 不放物品i:背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]。

  • 放物品i:背包空出物品i的容量后,背包容量为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

状态转移方程 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物品。

初始化后的表格为

4.确定遍历顺序

选择先遍历物品后遍历重量相对更好理解些

5.举例推导dp数组

代码

dp = [[0] * (bagweight + 1) for _ in range(n)]

for j in range(weight[0], bagweight + 1):
    dp[0][j] = value[0]

for i in range(1, n):
    for j in range(bagweight + 1):
        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])

print(dp[n - 1][bagweight])

 

举报

相关推荐

0 条评论