Day38 - 动态规划 Part06

37 阅读2分钟

基础

完全背包问题:

如果求组合数就是外层for循环遍历物品,内层for遍历背包。

如果求排列数就是外层for遍历背包,内层for循环遍历物品。

刷题

  1. 零钱兑换

leetcode.cn/problems/co…

image.png

动规五部曲:

  1. 确定dp数组含义 : 当总和为j,最少有dp[j]个硬币兑换

  2. 确定dp数组递推公式: dp[j] = min(dp[j], dp[j-coins[i]]+1)

  3. 确定dp数组初始化 dp[0] = 0 由于递推公式是取最小值,dp数组的非零下标值是math.MaxInt32

  4. 确定dp数组遍历顺序 先物品后背包 与 先背包后物品 都可以,因为不涉及排列和组合

  5. 打印dp数组

  6. 完全平方数

leetcode.cn/problems/pe…

image.png

思路和上一题一样

优化:

dp数组初始化可以初始化为[0, 1, 2, 3, 4, 5, 6...], 因为完全平方数有1,就不需要math.MaxInt32了,直接从物品2*2 开始遍历

dp[i*i]直接赋值为1,1就是最小的

  1. 单词拆分

leetcode.cn/problems/wo…

image.png

动规五部曲:

  1. 确定dp数组含义 j 是s的长度(背包) dp[j] 为是否可以拼凑出s[0:j+1] bool类型

  2. 确定dp数组递推公式 if wordDict[i] == s[j-物品长度:j] dp[j] = dp[j-物品长度]

  3. 确定dp数组初始化 dp[0] = true. 其他是false

  4. 确定dp数组的遍历顺序 排列,先遍历背包再遍历物品

  5. 打印dp数组

  6. 携带矿石资源

kamacoder.com/problempage…

image.png

多重背包

有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。

这个是多重背包问题,和01背包很像,每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了。

总结

math.MaxInt32   // 32位int最大值

背包问题总结

programmercarl.com/背包总结篇.html#…

image.png