动态规划专题(I)
来源:互联网 发布:图解网络硬件 kindle 编辑:程序博客网 时间:2024/04/30 21:07
动态规划与分治法类似,都是通过组合子问题的解来求解原问题。分治方法将问题划分为互不相交的子问题,递归的求解子问题,再将它们组合起来,求出原问题的解。与之相反,动态规划应用于子问题重叠的情况,不同的子问题具有公共的子子问题。这个时候,分治算法会做许多不必要的工作,它会反复的求解那些公共子子问题,而动态规划则对每个子问题只求解一次。举例来说,在之前的文章《排序算法总结》中,我们介绍了一些采用分治策略的算法,比如归并算法,快速排序算法等,它们会把数组分为两个部分,两个部分是不相交的,然后分别处理每个部分,这里就不存在重叠子问题。但是对于爬楼梯问题,如果采用递归解法,那么当我们算第4层的时候,会计算第3层与第2层,当我们计算第3层时,会计算第2层与第1层,可见第2层被重复计算了,这种情况下效率会很低,动态规划则能很好的处理这种问题。
设计一个动态规划的步骤:
1.刻画一个最优解的结构特征
2. 递归的定义最优解的值
3.计算最优解的值
4.利用计算信息构造出一个最优解
下面我们具体看一下。
刻画一个最优解的结构特征是第一步,也是最难的一步了,动态规划威力巨大,可不见得人人都能想到,这一点还要“靠感觉”,但是也有一些小的技巧帮助我们启发思维。首先动态规划有一维的,也有二维的,还有三维的(四维的很少见),这跟坐标系一样不同的维度,如果只涉及一个点集就是一维的,如果涉及到两个点集元素之间的关系则是二维的。。。,在解决动态规划问题时也有类似的规律。如果我们的问题只涉及一个对象,比如前面提到的爬楼梯问题,那么它很有可能是一维的,如果涉及到两个对象,比如最长公共子序列问题,那么它一般是二维的,这时它的结构就是int[][] dp = new int[len1][len2]的形式。当然,这也不能太绝对,leetcode上有一道题目(后面会介绍),涉及到三个对象,但是结果却是用二维dp解决的,这种情况一般是因为三者之间有固定的关系,可以使我们消掉一维,前面提到的这道题就是这种情况。还需要说明一点,我们上句话中提到的”对象“要正确理解,比如并不一定两个字符串才算两个对象,一个字符串也可能是两个”对象“,这主要是由我们研究的问题的结构决定的,比如找一个字符串中的回文子串问题。另外,我们发现动态规划与高中学习的数学归纳法有些类似,这也启发我们在解决这类问题时可以从一个小规模的问题开始尝试。我还常用的另一种方法就是假设,比如通过前面介绍的,我认为这是一个二维动态规划问题,那么我就会假设dp[len1][len2]就是我最终要求的解,然后从这个假设开始倒着推,看看能不能有什么新的发现。
在解决了上面的问题之后,动态规划还有一点可能会遇到的困难就是解的构造。比较复杂的就是通过dfs进行最终解的构造了,这种情况多加练习就可以了。
接下来一篇博客会通过具体的题目来加深dp的理解和应用。
参考
《算法导论》
- 动态规划专题(I)
- 动态规划专题(II)
- 第三专题总结(动态规划)
- HDU动态规划专题
- 动态规划专题:beginner
- 动态规划专题:BZOJ1207
- 动态规划专题
- 动态规划专题(III)
- POJ 动态规划专题
- 动态规划专题总结
- 动态规划专题总结
- 动态规划专题总结
- 动态规划专题
- LeetCode专题----动态规划
- 【专题】基础动态规划
- 动态规划专题
- 动态规划专题总结
- 动态规划专题总结!
- powerDesinger 反向工程mysql
- 获取系统内存使用情况
- 自定义ViewGroup相关
- java 获取文件夹中的全部文件名
- CentOS下安装KVM虚拟机的步骤,绝对有用!
- 动态规划专题(I)
- 周韦彤MFC IDC
- Atmega128L控制ADS7816进行AD采集的子程序(AVR单片机)
- 解决eclipse中Android SDK Manager更新慢和部分无法显示System Image镜像问题
- 【HTML5&CSS3进阶04】CSS3动画应该如何在webapp中运用
- LeetCode:Subsets
- rgb888与rgb565转换的影响
- 从QProcess说开来(一)
- Cocos2d-x中CCLabel字体类