zoukankan      html  css  js  c++  java
  • 动态规划

    动态规划是一个很好用的算法,同时也是令很多人头疼的算法,下面就介绍一下对动态规划的看法。
    通过学习和刷题我们可以发现动态规划一般是用于求一些最值问题,比如说最长递增子序列等等,我们要想知道一个问题的最值,就要知道问题的所有答案然后通过比较得出答案,也就说我们平常所说的穷举;当然肯定不是暴力的穷举,对于一些动态规划的这类问题来说都是存在重叠子问题的,动态规划的做法是可以采用“备忘录”或者DP数组来避免不必要的计算。
    动态规划的三要素是重叠子问题,最优子结构,状态转移方程;重叠子问题其实就是一些重新计算,比如我们之前计算过这个结果但是并没有保存,下次用到的时候需要重新计算,解决的方法可以是保存计算结果,下次用到的时候直接取用;最优子结构指的是问题的最优解包含子问题的最优解,也就是我们可以通过子问题的最优解推导出整个问题的最优解,要想有最优子结构,一般来说需要各个子问题之间是相互独立的;状态转移方程可以说是解决动态规划关键,当然也是挺困难的,大家可以通过多做题来感受一下,总结一下。
    之前在学习的时候看到别人进行了相关的总结,觉得写得很好,在这里同样记录一下,以免忘记:总结了动态规划的一般步骤是 明确base case,明确【状态】,明确【选择】,定义dp数组/函数的含义;
    并给出了一个一般的框架,如下所示:

    # 初始化 base case
    dp[0][0][...] = base
    # 进行状态转移
    for 状态1 in 状态1的所有取值:
        for 状态2 in 状态2的所有取值:
            for ...
                dp[状态1][状态2][...] = 求最值(选择1,选择2...)
    

    其中确定base case比较简单,一般就是可以直接得到答案不用计算的情况;
    确定【状态】,状态一般是原问题和子问题中会变化的变量;
    确定【选择】,选择指的是会导致状态发生变化的行为,具体问题具体分析;
    明确dp数组/函数的含义,一般来说定义dp函数是采用递归的方法,定义dp数组是采用递推的方式,递归是自顶向下的方法,一般函数的参数就是前文中的状态,dp数组一般是有几个状态就定义为几维的。
    大致的动态规划就先介绍到这里,后面有经典的习题会及时补充,同时还有一个空间优化的问题。

  • 相关阅读:
    外校培训前三节课知识集合纲要(我才不会告诉你我前两节只是单纯的忘了)
    floyd算法----牛栏
    bfs开始--马的遍历
    (DP 线性DP 递推) leetcode 64. Minimum Path Sum
    (DP 线性DP 递推) leetcode 63. Unique Paths II
    (DP 线性DP 递推) leetcode 62. Unique Paths
    (DP 背包) leetcode 198. House Robber
    (贪心 复习) leetcode 1007. Minimum Domino Rotations For Equal Row
    (贪心) leetcode 452. Minimum Number of Arrows to Burst Balloons
    (字符串 栈) leetcode 921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/noob-l/p/13619928.html
Copyright © 2011-2022 走看看