基础
完全背包问题:
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
刷题
- 零钱兑换
动规五部曲:
-
确定dp数组含义 : 当总和为j,最少有dp[j]个硬币兑换
-
确定dp数组递推公式: dp[j] = min(dp[j], dp[j-coins[i]]+1)
-
确定dp数组初始化 dp[0] = 0 由于递推公式是取最小值,dp数组的非零下标值是math.MaxInt32
-
确定dp数组遍历顺序 先物品后背包 与 先背包后物品 都可以,因为不涉及排列和组合
-
打印dp数组
-
完全平方数
思路和上一题一样
优化:
dp数组初始化可以初始化为[0, 1, 2, 3, 4, 5, 6...], 因为完全平方数有1,就不需要math.MaxInt32了,直接从物品2*2 开始遍历
dp[i*i]直接赋值为1,1就是最小的
- 单词拆分
动规五部曲:
-
确定dp数组含义 j 是s的长度(背包) dp[j] 为是否可以拼凑出s[0:j+1] bool类型
-
确定dp数组递推公式 if wordDict[i] == s[j-物品长度:j] dp[j] = dp[j-物品长度]
-
确定dp数组初始化 dp[0] = true. 其他是false
-
确定dp数组的遍历顺序 排列,先遍历背包再遍历物品
-
打印dp数组
-
携带矿石资源
多重背包
有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。
这个是多重背包问题,和01背包很像,每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了。
总结
math.MaxInt32 // 32位int最大值
背包问题总结
programmercarl.com/背包总结篇.html#…