[路飞]_动态规划,学算法的必经之路

273 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

动态规划 Dynamic Programming

四个要点:

  1. 递推(递归 + 记忆化 ==>递推,初级使用的方式,熟练后可以直接用递推),递归的最底层有初始值,所以从下往上的方式推上去就可以得到结果,这种方式就是递推
  2. *状态的定义:opt[n],dp[n],fib[n]
  3. *状态转移方程(dp方程):opt[n] = bestOf(opt[n-1] + opt[n-2], ...)
  4. 最优子结构

斐波拉契数列(初级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 —— 记录局部最优子结构

    当回溯存在重复计算的时候,通过缓存的形式把局部最优值记下来,避免重复计算。再通过动态的转移方程,去推导下一个状态的最优值,达到动态规划的效果