动态规划
思想
动态规划(Dynamic Programming DP)最核心的思想,就在于拆分子问题,记录子问题的解,减少重复计算
动态规划适用的问题通常有重叠子问题和最优子结构 链接
记录子问题的解,会增加空间复杂度,动态规划通过空间复杂度换取时间复杂度
步骤
- 定义状态:将原问题转化为更小的子问题,并定义状态来表示子问题的解
- 确定状态转移方程:根据子问题之间的关系,推导出状态转移方程,用于计算当前问题的解
- 初始化:初始化边界条件,即最小的子问题的解
- 递推计算:按照状态转移方程,从边界条件开始逐步计算出所有子问题的解,直到得到原问题的解
- 返回结果:返回原问题的解
01背包
js
function testWeightBagProblem(weight, value, size) {
// 定义 dp 数组
const len = weight.length
const dp = Array(len)
.fill()
.map(() => Array(size + 1).fill(0))
// 初始化
for (let j = weight[0]; j <= size; j++)
dp[0][j] = value[0]
// weight 数组的长度len 就是物品个数
for (let i = 1; i < len; i++) {
// 遍历物品
for (let j = 0; j <= size; j++) {
// 遍历背包容量
if (j < weight[i])
dp[i][j] = dp[i - 1][j]
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
}
}
return dp[len - 1][size]
}
console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6))
function testWeightBagProblem(weight, value, size) {
// 定义 dp 数组
const len = weight.length
const dp = Array(len)
.fill()
.map(() => Array(size + 1).fill(0))
// 初始化
for (let j = weight[0]; j <= size; j++)
dp[0][j] = value[0]
// weight 数组的长度len 就是物品个数
for (let i = 1; i < len; i++) {
// 遍历物品
for (let j = 0; j <= size; j++) {
// 遍历背包容量
if (j < weight[i])
dp[i][j] = dp[i - 1][j]
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
}
}
return dp[len - 1][size]
}
console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6))