70. 爬楼梯 (进阶)
https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html
- 考点
- 完全背包
- 我的思路
- 本题就是用完全背包的思路解决排列问题,一个背包、多个物品(无限拿取)求装满背包有多少种排列
- 视频讲解关键点总结
- 无视频
- 我的思路的问题
- 无
- 代码书写问题
- 无
- 可执行代码
class Solution:def climbStairs(self, n: int) -> int:dp = [0] * (n + 1)dp[0] = 1for j in range(1, n + 1):for i in range(1, 3):if j >= i:dp[j] += dp[j - i]return dp[-1]
322. 零钱兑换
视频讲解:https://www.bilibili.com/video/BV14K411R7yv
https://programmercarl.com/0322.%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2.html
- 考点
- 动态规划
- 完全背包
- 我的思路
- 给定一个背包容量和多个物品,求装满背包使用的最少物品个数,如果物品无法装满背包,返回-1
- dp[j] 的含义是当容量为 j 时,装满背包所用的物品的最少个数
- 递推公式,dp[j] = min(dp[j], dp[j - coins[i]] + 1),求取当前物品和不取当前物品对应的最小值为dp值
- 关键点1,初始化,这是一个本题的关键
- 首先当j 为 0时,初始化dp为0,这点没有问题
- 对于剩下的dp数组(非零下标),应该怎么初始化?这就要基于递推公式来分析了,递推公式中对于后续每个值,都是基于最小化的思想来迭代的,如果dp数组全初始化为0,则后续递推过程由于取最小值,整个dp数组将保持为0;所以,应该在初始化时,把后面的dp值初始化为一个极大值,这样才能保证递推过程正常进行
- 遍历顺序——内外双循环(可以相互颠倒,因为本题既不是组合问题也不是排列问题,求最小数量和取物品的顺序无关),内外层循环均正向遍历(因为是完全背包问题,每个物品可以取多次)
- 关键点2,对于物品无法装满背包的判断
- 什么情况下物品装不满背包?其实就是无论怎么组合,背包最后所剩的容量小于重量最小的物品,这种情况下背包无法装满
- 由于在递推公式中,如果背包容量小于物品重量,该dp值将保持初始化时的极大值,因此,如果dp递推结束后,对应的dp[-1]的值为初始化的极大值,则代表背包无法装满,此时返回-1
- 视频讲解关键点总结
- 本题求最小数量既不是组合问题也不是排列问题,其与取物品的顺序无关
- 我的思路的问题
- 对于内外层循环是否能颠倒一开始没想明白,以为本题是组合问题,其实本题无关顺序
- 代码书写问题
- 可以利用
float('inf')
来取极大值
- 可以利用
- 可执行代码
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:dp = [float('inf')] * (amount + 1)dp[0] = 0for i in range(len(coins)):for j in range(1, amount + 1):if j >= coins[i]:dp[j] = min(dp[j], dp[j - coins[i]] + 1)if dp[-1] == float('inf'):return -1return dp[-1]
279.完全平方数
- 考点
- 动态规划
- 完全背包
- 我的思路
- 先找到所有比目标值小的完全平方数(可以通过
int(sqrt(i)) == sqrt(i)
来判断) - 之后背包容量是目标值,物品是完全平方数集合,无限次拿取,看装满背包的最小物品数是多少
- 先找到所有比目标值小的完全平方数(可以通过
- 视频讲解关键点总结
- 关键点1,不需要寻找完全平方数,从1开始遍历数字 i ,之后递推公式里用 i ** 2 代替 i 即为使用完全平方数了
- 关键点2,遍历背包容量时从i ** 2开始遍历即可,因为小于该数值,当前物品一定无法被放入背包,所以dp值不变,不需要进行额外操作
- 我的思路的问题
- 遗漏一个关键,本题一定能找到满足题意的组合,因为完全平方数里有1,能组出来任意数字
- 光想着如何判断一个数字是不是完全平方数了,没想到可以直接通过顺序遍历得到所有的完全平方数
- 代码书写问题
- 无
- 可执行代码
class Solution:def numSquares(self, n: int) -> int:dp = [float('inf')] * (n + 1)dp[0] = 0for num in range(1, int(sqrt(n)) + 1):for j in range(num ** 2, n + 1):dp[j] = min(dp[j], dp[j - (num ** 2)] + 1)return dp[-1]