动态规划与贪心算法
来源:互联网 发布:监控远程控制软件 编辑:程序博客网 时间:2024/05/21 08:44
动态规划的实质是分治思想和解决冗余,动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最优化问题的算法策略。
《转载》算法学习——动态规划策略入门
一、概念
动态规划策略,一种分治策略。和贪婪策略一样,通常是用来解决最优解问题。分治故名就是将问题分解为几个子问题来解决,动态规划的特点就是分解的子问题中(子问题又可以分解成子问题)每次选择选择最优解。
动态规划主要的特点是在做决定前她知道所有子问题的信息。
动态规划的两个重要要素是:1)最优子结构。2)重叠子问题。
1)最优子结构,这是采取动态规划策略解最优化问题后要做的第一步。所谓最优化子结构是说若问题的一个最优解中包含了子问题的最优解,则该问题具有最优子结构。这个是我们采取动态规划的一个充分条件(当然这个条件也满足贪婪策略),问题出现这个条件就可以考虑采取动态规划。
一般要考虑的因素是:
1.1)最优解里需要解决的子问题数量有多少?
1.2)在判断使用那些子问题时需要进行多少选择?
2)重叠子问题,是指在递归解决方案中,若产生了大量的相同子问题,那么相同的子问题就会被重复计算很多次,这样算法的效率损耗就很大。这个要素是动态规划的优势所在,可以说动态规划就是为解决这种问题而生的(实际上,有记忆的递归算法也可以做到类似的算法改进).
二、解题策略
一般解题的思路为:
1)证明问题的解决方案中包括一个选择,选择之后将留下一个或多个子问题
2)设计子问题的递归描述方式(一般会出现递归公式又称转移方程,这个是解题和算法的关键)
3)证明对原问题的最优解里包括对所有子问题的最优解
4)证明子问题之间有重叠
可以看出1、3、4是为了使得子问题的构建能符合动态规划策略,他们的目的都是为了他构建一个合理恰当的子问题而服务的。但是不同问题构建子问题的思路不尽相同。除了要考虑1.1、1.2的问题外,通常有个比较有效的经验,就是尽量使得这个子问题简单,然后在需要的时候去扩充她.
三、例子
用比较经典的最长公共子序列问题(LCS)。
问题定义如下:两个子序列S1[1..m]和S2[1..n],需要找出他们的一个最长公共子序列(其中子序列不一定必须是连续的)。
解法一:暴力穷举法
思路:
1)检查S1[1..m]中的每一个子序列.
2)看看其是否也在S2[1..n]里的子序列.
3)在每一步记录当前找到的子序列里面最长的子序列.
显然效率非常低下:每个子序列的检查要时间O(n),而共有2^m子序列需要检查,so时间复杂度问O(n*2^m).
那么如何改进呢,由于LCS中存在最优子结构,即所求的最长公共子序列包含子最长公共子序列,所以我们可以尝试使用动态规划来解决问题.
解法二:动态规划
按照解题策略,我们要先构造一个合适的子问题,根据第二点提到的,我们构建一个尽量简单的子问题,然后在去扩展.在LCS中,便有:
1)先寻找最长公共子序列的长度.
2)扩展寻找长度的算法来获得最长公共子序列.
由上可以得到一个递归表达式:
( c[i,j]表示长度为i的S1和长度为j的S2的最长公共子序列. xi表示表示S串中的第i个字符. )
上面递归式的推倒通过画图可以很容易得出.
代码:
四、小结
LCS的变种还有很多:最长递增/递减子序列、编辑距离等.
动态规划的关键还是以上提到的两个重要的元素:最优子结构和重复子问题.最优化问题中若出现了相关的信息或可以转换到此类问题的则可尝试使用动态规划.但是子问题的构建需要花费一定的思考即构建递归方程式.
但是,动态规划的虽然能做出最"明智的"决定,但她需要对一切"了如指掌"后才能做到,这显然趋于"保守",所以并非所以问题都适用.这个时候其它最优化算法可以被考虑.
- 动态规划与贪心算法
- 动态规划与贪心算法
- 动态规划 分治算法与 贪心算法
- 动态规划与贪心算法的区别
- 动态规划与贪心算法的比较
- 分治法、动态规划与贪心算法
- 贪心算法与动态规划的比较
- 贪心算法与动态规划区别
- 贪心算法&动态规划
- 贪心算法,递归算法,动态规划算法比较与总结
- 贪心算法,递归算法,动态规划算法比较与总结
- 贪心算法,递归算法,动态规划算法比较与总结
- 理解动态规划算法与贪心算法区别----找钱问题
- 算法导论小结(8)-动态规划与贪心算法
- 贪心算法与动态规划算法的异同
- 动态规划与贪心算法的区别与联系
- 动态规划与贪心算法的区别与联系
- 贪心算法和动态规划
- Spring两种注入方式的区别
- cocos2dx项目中新增场景类
- spring详解(一)
- myeclipse 一些提示信息快捷键设置
- HDU 1978 DP
- 动态规划与贪心算法
- 面试100题:2.设计包含min函数的栈
- 函数指针和回调函数
- 2013年五大主流浏览器 HTML5 和 CSS3 兼容性大比拼
- perl中重要的几个命令行参数
- 如何跟踪调试Android的源码
- win32 查找注册表找网卡
- 路径的写法
- Android permission 访问权限大全