动态规划可以称得上是算法题里最常见的一种题型,而且一些算法题除了动态规划使用别的方法会使得效率变得极低。现在就将动态规划的学习知识点记录以下。
判断一个问题是不是能用动态规划来求解主要是两个点:1,是否具有最优子结构,这里面也就包含子问题的解是不是相关,子问题是不是会一直重复,必须足够小。2,能形成状态转移方程,也就是开始求的数值,在后来叠加时能够使用,也可以说是重叠。如果一道题能找到这两个问题点,并且清晰的将状态转移方程写出来,那么算法可以说是解决了一半。
那么最优子结构怎么找呢?当有很多条件时,怎么将条件放入状态转移方程呢?这里我们需要分类来说一下几个基本的方法。
最优子结构分成两种求法:1,从中间扩散,也就是组合从一个开始,到两个,到多个,一直到最长的长度,从每个位置开始的中间扩散(最优二叉搜索树)。2,从低位到高位,也就是依次累计计算得到之前的问题(切钢条)。基本上碰到的最优子结构的构思就是这两种。
从低位到高位的情况:将题目的变化按两个条件维度增长变化分成一个二维表格通过对从低位到高位依此增加,对不同条件的情况的结果也就在这个表格中。而这个一定条件的寻找就是问题的关键。当然在你勾画表格的时候你就需要想好,怎么去构建这个状态转移方程,而表结构的出现是使得你的方程更加清晰。这两者在解题过程中是互相辅助的。得到的优解基本就是上个所有优解加现在的值递减的一个过程
中间扩散是从二维边成一个一维的数组,这个是特定情况,就类似最优二叉搜索树里面,一个个组合得到一些最优解,类似这种树结构或者类似()的结合,需要绑定在一起的这类问题,都可以使用这种中间扩散的办法。这种的状态转移方程就是从(i,j)这样扩散达到题目的解。
在构思最优子结构之前,可能还需要思考一点的就是原本的目标结构的顺序需不需要改变,有些题目改变顺序之后算法就能简化很多(双调欧几里德旅行商问题)。
差不多上面就是动态规划的一些总结,算法这个看是看不会的,必须自己动手做,多思考。算法导论后面的几道思考题大家可以做一遍基本上就能摸到这个方法的一点小门道,而动态规划的路子在我看来毕竟是有限的,只是方法实现不同所得到的效率的差距,这就是需要进阶的地方了。在写一些算法题时,有些题很明了看样式就知道怎么解,但是有些题很隐晦,我们得用不同得方式去套着试试(也许是我修行并不够)。多一些思路方法,解题得路子就 自然会多起来。最后建议大家在解完一道题之后,将答案的复杂度都分析一下,有没有还能优化的点,网上找找别人怎么做的。这样才能有进步,不然做出来就不管跟没做是没什么区别的。 下一章:贪心算法。