「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
动态规划 Dynamic Programming
四个要点:
- 递推(递归 + 记忆化 ==>递推,初级使用的方式,熟练后可以直接用递推),递归的最底层有初始值,所以从下往上的方式推上去就可以得到结果,这种方式就是递推
- *状态的定义:opt[n],dp[n],fib[n]
- *状态转移方程(dp方程):opt[n] = bestOf(opt[n-1] + opt[n-2], ...)
- 最优子结构
斐波拉契数列(初级DP)
递推公式
F[n] = F[n-1] + F[n-2]
状态转移方程
F[0] = 0,F[1] = 1
for (let i = 2; i <= n; i++) {
F[i] = F[i-1] + F[i-2]
}
最大递增子序列
递推公式
dp[i] = Math.max(dp[0], dp[1], ... dp[n-1])
状态转移方程
for (let i = 0; i < n; i++) {
for (let j = 0; j < i; j ++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1)
}
}
}
COUNT THE PATHS
递推公式
opt[i, j] = opt[i-1, j] + opt[i, j-1]
状态转移方程
for (let i = 0; i < m; i++) {
for (let j = 0; i < n; j++) {
if (a[i, j] === '空地') {
opt[i, j] = opt[i-1, j] + opt[i, j-1]
} else {
opt[i, j] = 0
}
}
}
DP vs 回溯 vs 贪心
-
回溯(递归) —— 重复计算
没有最佳子结构的时候,回溯就是最优解法,穷举所有的可能
-
贪心 —— 永远局部最优解
局部最优解就是全局最优解的时候可以使用
-
DP —— 记录局部最优子结构
当回溯存在重复计算的时候,通过缓存的形式把局部最优值记下来,避免重复计算。再通过动态的转移方程,去推导下一个状态的最优值,达到动态规划的效果