动态规划学习心得

 关于动态规划(dp),首先它非常重要,用老师的话说就是:要是动态规划这里出了问题,那最好退出。对于其定义网上很多这里不再赘述,在这里就记录一下自己作为一个初学者(甚至称不上初学)它的几点理解。
(一)学习感悟:
    对于一个问题还是比较容易确定是否采用动态规划的,因为它是用来求最优值的,一旦题目中有和最优相关的词语就得考虑一下它了(虽然不一定用)。假如做过的题多了,根据经验是比较容易确定的。但是动态规划定义虽然简单,用起来却是另一回事。即使你知道要用动态规划却不一定真正根据题目应用好,由于现在自己做看题目很少(数一下也就背包,最大字段,最长公共子序列,基因匹配,最大矩阵连乘积等),仅仅能做那几道相似的题目(所以为了挽救自己的自信,我做完一道题后提交好几遍多几个ac也是安慰)。老师曾说过:“动态规划看不100道题就不算入门。”所以这里还要花很长时间。以后慢慢看细细看即使把自己的心得记录一下(也是老师的要求)。
(二)分析过程:
    对于一道具体的题目现在我的理解是可以先举出几个比较简单的例子来分析一下,进而扩展到整体。因为动态规划在解决问题的过程中就是利用开始的初值以后枚举各种情况从而确定下一阶段的最优情况并记录其值(正是因为这个dp用的数组才有了特殊意义),这样推下去就得到了最终的最优解。目前为止,自己感觉这种记录中间阶段最优值得方法是dp的重要部分,基因这个它才能把问题分阶段,因为这个才去除了冗余,刚开始是一一枚举(这也符合我们的思维,因为有些题没有数学公式带入后直接求解)但是随着每个最优解被记录下来,越往后省去的运算越多(从数字塔问题中明显看得出)。对于一个很大的问题根据dp是状态转换方程一步一步往前推,现在自己还不能完全适应,因为问题的解决过程是自下而上的,由易到难的,这种推理方式与其刚好相反。所以还是得多看点题,写完代码后仔细看看程序是怎么运行的,以渐渐适应这种方式。
(三)状态转移方程
    这无疑是接下来编写程序的根据,只要对问题有所理解并且划分出具体阶段是比较容易得出的。不过目前对于我来说能独立得出的也就难几类题,还是做题少啊。在这里主要说说自己的一点小体会,由于dp是要最优值,所以这个方程也是从好多情况中去最优值,所以枚举各种情况时就像数学中的分类讨论,一定要做到不重不漏(有时就是这个让自己卡上好长时间),所以在列举各种情况,确定循环的范围是要谨慎。
(四)动态规划编程:
    写代码从来不是解决一个问题的核心,假如有了思路,这里还是很容易解决的。最近做的几道也有了点收获。就像前面说的,dp是自下而上的,所以开始要赋好值。还有,dp是有计算次序的(例如最大矩阵连乘积等问题中,刚开始解决的是相邻元素的合并情况)所以在循环变量有时要特殊处理一下。dp确定的数组一般有特殊意义这点是有利于编程的。
(五)问题
1.目前理解不深,例如那个数组的确定。dp数组有二维的有一维的,这还能接受毕竟不同问题不同需要。不能接受的是为什么二维的有时能够转换成一维的(比如背包优化后就可以,还有那个节约空间的优化还是有些不懂)这点自己有了点眉目,不过还没吃透。
3.关于动态规划应用的条件,无后效性、最优子结构这些理解起来挺容易,但是拿到一个具体的问题有时就不好说了,这也是在写状态转换方程是会碰到的问题,有时写着写着就把阶段推的太靠前或太靠后。
4.在对一个问题分阶段,除了线性、区间类型这几种目前见得多的情形,对其他情况还是不太会处理,不过近来思路似乎有些变了,适应了一点。
posted @ 2013-08-07 20:33  Neptunes  阅读(2100)  评论(0编辑  收藏  举报