动态规划——系列问题总结(持续更新)
一、理解动态规划
下面先总结一下我从上述两位知乎网友的回答中收获的心得:
- 把问题描述的更”IT“一些,也就是用更接近数学和计算机的语言来把原来的实际问题抽象化,这样很有利于我们用更清晰的思路去解决问题
- 在上述进一步抽象的问题描述中找准状态和状态之间的转化关系
- 关于上面说的几种算法思想的区分,这里引用一下上述知乎网友@王勐的回答:
- 每个阶段只有一个状态—>递推(例如Fibonacci数列)
- 每个阶段的最优状态都是由上一个阶段的最优状态得到的—>贪心(例如背包问题)
- 每个阶段的最优状态是由之前所有状态的组合得到的—>搜索(例如迷宫问题)
- 每个阶段的最优状态是由之前的某个阶段的某个状态或者某些状态得到的,并且我们不用管这个状态究竟是怎么得到的—>动态规划(例如我一会要讲的这个问题)
二、相关问题
1. 求解数列中递增数列的长度
问题:
给定一个数列,长度为N,求这个数列的最长上升(递增)子数列(LIS)的长度.
以1 7 2 8 3 4为例。
这个数列的最长递增子数列是 1 2 3 4,长度为4;
次长的长度为3, 包括 1 7 8; 1 2 3 等.
解法思路:
首先构造出这个问题的数学模型,即
F_{1} = 1 (根据状态定义导出边界情况)
F_{k}=max(F_{i}+1 | A_{k}>A_{i}, i\in (1..k-1)) (k>1),
其实上面的问题就可以归结为这个公式,有了这个公式就有了更明确的思路了,下标为k时的结果就是下标为k-1时的结果+1(如果[k]元素比k之前的最长递增数列的最后一个数大的话),否则就还是下标为k-1时的结果,这样递归下去,就能得到最终的结果了。
def longest_sub_increase(list,k):
size = len(list)
if size == 1 or k == 0:
return 1
max_len = -1;
for index in xrange(k):
if list[index] < list[k]:
max_len = max(max_len,longest_sub_increase(list,index)+1)
else:
max_len = longest_sub_increase(list,k-1)
return max_len
list = [1,2,3,5,1,1]
max_len = longest_sub_increase(list,len(list)-1)
print max_len
本人是软件工程专业的在校大学本科生,喜欢编程的小伙伴可以加我QQ一起探讨,QQ:312805939