0%

完全背包问题总结

完全背包问题总结

首先,需要清楚的是对于完全背包问题的定义:有N件物品和一个最多能背重量为 W 的背包。第 i 件物品的重量是 weight[i] ,得到的价值是 value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

相较于0/1背包问题,完全背包问题最大的不同之处在物品的个数是无限。那么在进行选择时,就是每一次向背包中添加物品时,都有 n 个物品可供选择(即从所有的物品中做任意的选择)。

完全背包问题的实现只需要在0/1背包的基础上稍作改动即可,依旧是采取滚动数组实现。

  1. 对于先便利物品,再遍历背包的情形:那么完全背包相较于0/1背包的不同之处,在第 i 次迭代时,0/1背包只能使用一次物品 weight[i] ,因此采取从后向前的方式遍历,为了防止重复选择,但是完全背包可以使用任意次物品 weight[i] ,所以需要实现重复的选取,因此采取从前向后的遍历方式即可。并且这种先遍历物品再遍历背包的方式,本质上是在求解组合问题,也就是对于物品的选取顺序是不敏感的,仅对物品的个数敏感。(因为先遍历物品,因此也就确定了选取的顺序)

  2. 先遍历背包,再遍历物品:也就是对于每一种情形下的背包容量,都从全部的物品中进行选择。在单纯的完全背包问题下,递推公式和结果是不会改变的。但是这样的遍历方式,本质上是在求解排列问题,也就是对于物品的选取顺序是敏感的,因为先遍历的是背包容量,在背包容量增大的过程中,最后一次选取的物品不同将会是不同的情形。

LeetCode 377 组合总和Ⅳ

377.组合总和 Ⅳ

给你一个由不同整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

本题求解的并不是组合问题,是一个排序问题,在题目示例中将 1,2,11,1,2 视为两种不同的组合,也就是对于元素的选取顺序是敏感的。那么应该先遍历背包再遍历物品,并且此处求解的是恰好装满的情形,相应的递推公式为 dp[j]+=dp[j-nums[i]]

LeetCode 518 零钱兑换II

518.零钱兑换II

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0

根据题中的示例,本题求解的是一个组合问题。

并且此处的背包问题是一个恰好装满的情形,那么对于组合问题基本思路就是先遍历物品再遍历背包,那么递推公式为: dp[j]+=dp[j-coins[i]] ,在进行初始化是一定要将 dp[0]=1

LeetCode 322 零钱兑换

322.零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

此处的最优化问题为:求解能够恰好装满背包的最少硬币数量,那么对于组合和排列都是相同的,两种遍历顺序都是可以的。基本的递推公式为:dp[j]=min(dp[j],dp[j-coins[i]]+1) ,要让上述递推公式成立,需要在数组的初始化时进行特殊处理,对于 dp[0] 只需要0个硬币即可装满。那么对于其他的值明显都装不满,因此初始为 INT_MAX ,并且每次判断 dp[j-coins[i]]!=INT_MAX

LeetCode 279 完全平方数

279.完全平方数

给你一个整数 n ,返回和为 n 的完全平方数的最少数量 。

完全平方数是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

此处和上述问题是非常类似的,也是在求解将背包恰好装满的最少的元素数量。但是此处的元素要求是完全平方数,因此在遍历物品的同时去生成相应的完全平方数即可。对于 dp[0] 依旧是初始化为0。其他元素全部初始化为 INT_MAX 。对应的递推公式为 dp[j]=min(dp[j],dp[j-nums[i]]+1) 要求 dp[j-nums[i]]!=INT_MAX

LeetCode 139 单词拆分

139.单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

此处需要注意的是:本题是一个排列问题,一定要先遍历背包,再遍历物品,也就是对于任意的背包大小都要能够使用全部的物品去进行填充,否则对于 applepenapple 这样的情形,在仅使用 apple 时,不能将后续的也标记为装满。那么在使用 pen 去填充时,无法使用 apple 将后续填满。

-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道