原理
基本思想
问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;
若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。
使用条件
可分为多个相关子问题,子问题的解被重复使用
- Optimal substructure(优化子结构)
- 一个问题的优化解包含了子问题的优化解
- 缩小子问题集合,只需那些优化问题中包含的子问题,降低实现复杂性
- 可以自下而上的
- Subteties(重叠子问题)
在问题的求解过程中,很多子问题的解将被多次使用。
设计步骤
设计状态
分析优化解的结构
状态转移
递归地定义最优解的代价
自底向上地计算优化解的代价保存之,并获取构造最优解的信息
根据构造最优解的信息构造优化解
特点
把原始问题划分成一系列子问题;
求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时直接存取,不重复计算,节省计算时间
自底向上地计算
整体问题最优解取决于子问题的最优解(状态转移方程)(将子问题称为状态,最终状态的求解归结为其他状态的求解)
求解概念
无后效性
如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响。
“未来与过去无关”,这就是无后效性。
例如:要求出f(15),只需要知道f(14),f(10),f(4)的值,而f(14),f(10),f(4)是如何算出来的,对之后的问题没有影响。
最优子结构
大问题的最优解可以由小问题的最优解推出,这个性质叫做“最优子结构性质”
案例
最长上升子序列
给定长度为n的序列a,从a中抽取出一个子序列,这个子序列需要单调递增。问最长的上升子序列(LIS)的长度。
e.g. 1,5,3,4,6,9,7,8的LIS为1,3,4,6,7,8,长度为6。
设计状态
令dp[i]表示以第i个元素结尾的前i个元素构成的最长不下降子序列的长度
状态推导
考虑比i小的每一个j;若ai>aj ,dp(x)可取 dp(p)+1
状态转移方程可表示为
dp[i] = max{dp[j] | 0<j<i , aj≥ai} + 1