背包问题
背包问题
c葱c
这个作者很懒,什么都没留下…
展开
-
leetcode 139.单词拆分
将字符串当作是背包,字符串数组里面的元素当作物品,本题求的是,物品能否将背包装满。为了后面递推公式的计算这里初始化 dp [ 0 ] = true。因为这里不同的顺序意味着不同的字符串,所以对顺序是由要求的。{ap} {pa} 不能看作是同一个字符串。先 背包 后 物品 ,求的是排列数。1. dp 数组的含义。原创 2023-04-29 16:38:35 · 45 阅读 · 0 评论 -
279.完全平方数
本题和零钱兑换 1 十分类似 ,只是物品变了,物品变成了 i * i。原创 2023-04-28 18:00:11 · 39 阅读 · 0 评论 -
322. 零钱兑换 ( 完全背包
这里 + 1 表示放入了 i ,所以个数 + 1。和之前加价值不一样,因为dp数组的含义变了。凑到 0 ,不需要硬币,所以数量也为 0 ( 这里和之前也不一样。因为求的的硬币的个数,而不是方案的数量,所以嵌套的前后也不会影响。放入 i :dp[j - coins[i]] + 1。由于是完全背包, 所以都是顺序遍历。不放入 i :dp[j]下标:需要凑到的钱总和。值:最小需要多少个硬币。1. dp数组的含义。原创 2023-04-28 17:41:28 · 70 阅读 · 0 评论 -
leetcode 70. 爬楼梯 (完全背包
之所以是完全背包是因为,之前上了一阶 后面还能继续上一阶。物品 是 一次能够上的台阶数 1 2 3......背包容量是一共要上的台阶数。这道题也可以用背包来解决。演变为完全背包的问题。原创 2023-04-28 17:31:08 · 37 阅读 · 0 评论 -
leetcode 377. 组合总和 Ⅳ (完全背包
先确定背包的大小,再遍历物品,这样就会出现 { 2 , 1 } { 2 , 1 } 的情况,因为物品是在内循环中,很有可能会出现先加入了大的,后加入小的 的情况。和零钱兑换的那道题基本一模一样,不同点在于最后 for循环嵌套先后。先背包,后物品(排列。这里需要防溢出 ( C++原创 2023-04-27 19:33:34 · 48 阅读 · 0 评论 -
leetcode 518. 零钱兑换 II (完全背包
取 i : dp [ j - conis[ i ] ] 也就是凑到剩余 j - conis[ i ],需要的方案。dp [ 0 ] = 1,如果初始化成 0 , 那之后都是 0 , 无法递推累加了。且背包需要正序遍历,因为物品是可以重复取得,且不受上一层得影响。本题是求:一共有多少种方法可以将背包装满 ( 与目标和 那道递推公式类似。不取 i : dp [ j ]值:凑到当前和有多少种方法。1. dp [ j ] 数组的含义。原创 2023-04-27 17:49:58 · 650 阅读 · 0 评论 -
leetcode 474.一和零 (01背包 二维
背包倒序:因为也是要使用到之前的 dp[i - zeroNums][j - oneNums] 的状态。dp[0][0] = 0 当前没有放入任何东西,其它的跟之前题一样,初始化成最小的非负整数。下标:i 表示 0 的数量,j 表示 1 的数量。这里涉及到三个变量: 0 的个数,1 的个数,背包中的数量。这个 + 1 就是表示背包中多了一个字符串。值:表示当前背包的放入字符串的最大数量。不放入当前的字符串:dp[i][j]1. dp[ i ] [ j ] 的含义。所以不能压缩成一维的 01背包。原创 2023-04-27 15:18:24 · 391 阅读 · 0 评论 -
leetcode 494. 目标和 (01 背包
意思是,如果选择了 i , 则 剩下要组成和为j - nums [ i ] 的方案数就等于dp[ j - nums [ i ] ]例如:集合 [ 0 ] target = 0 , 此时就只有一种方法。需要求出和为 (target + sum(nums)) / 2 的方案有多少个。就当作是 和 为0 的方式 只有一种。分成两个集合 (注意这里计算的时候是不带上符号的,只是单纯的数字。选i :dp [ j - nums[ i ] ]值: 和为 j 的方案有多少个。和之前一样,物品正序,背包倒叙。原创 2023-04-27 11:34:27 · 689 阅读 · 0 评论 -
leetcode 1049. 最后一块石头的重量 II (01背包
然后求这 两堆之差 sum - dp [target] - dp [target]首先就将这一堆石头尽量分成两堆一样重量, 重量: target = sum / 2。两堆 dp [target] sum - dp [target]这里的规则是求出碰撞后最小的石头是多少。与 01 背包 分割子集的题目类似。求出这一堆石头总的重量 sum。原创 2023-04-27 09:37:54 · 32 阅读 · 0 评论 -
416. 分割等和子集 (01背包
这样做的目的是,如果找到了 sum/2 ,那么剩下的一部分,必然是 sum / 2,也就是元素相等。都初始化成最小的非负整数,也就是0。如果太大就会把其它的覆盖掉。所以我们希望找的是 dp [target] = target。和 01 一维的一样。不过这里需要注意的是 价值 == 重量。把这个数组所有元素的和 / 2 ,得到一个target。也就是刚好装满,这里的元素的 价值等于重量。物品在外层,背包在内层,且一定要倒序。值:表示背包当前容纳的价值。原创 2023-04-26 21:08:08 · 37 阅读 · 0 评论 -
01 背包 (一维)
dp [ j - weight[i] ] + value[ i ] 是放入 物品 i ,dp [ j - weight[i] ] 是没放入 物品 i 之前的最大价值 ,现在放入物品 i , 就是放入物品 i 后的最大价值。dp [ i ] [ j ] dp [ i - 1] [ j ] 正是因为有 i 这个变量作为维度,所以就保留了上一层的状态。因为dp数组中的 i j 需要的是左上 和 上方 的值,与遍历顺序无关。我们可以利用到上一层的信息,根据上一层的信息,得到本层的信息。原创 2023-04-26 16:55:26 · 334 阅读 · 0 评论 -
01 背包 (二维 )
放物品 i : dp[ i ] [ j ] = dp[ i - 1 ] [ j - weight[ i ] ] + value[ i ] )不放物品 i :dp[ i ] [ j ] = dp[ i - 1 ] [ j ] (也就是,和上一层的值是一样的。有一个背包可以放下 n kg,有一些物品,价值和重量一一对应,问题是,需要怎样才能使背包中的价值最大?因为当前的值,是依靠左上 或者 上方的 值来的,和遍历顺序没有关系。1.dp[ i ] [ j ] 数组的含义。原创 2023-04-26 16:11:43 · 646 阅读 · 0 评论