动态规划——线性DP

动态规划——线性DP

最长不下降序列(LIS)

暴力搜索:由可行的所有起点出发,搜索出所有的路径。

动态规划——线性DP_第1张图片

但是深搜的算法时间复杂度要达到 O ( 2 n ) O(2^n) O(2n) (每个数都有选或不选的两个选择),指数级的时间复杂度在本题中( n ≤ 100 n≤100 n100)显然是不能接受的。那么再观察这个这棵递归树,可以发现其中有很多重复的地方。

动态规划——线性DP_第2张图片

那么如何优化呢?

首先可以使用数组将重复的部分记录下来,此后遇到相同的状态直接引用已经记录在数组中的数据即可,这样的方法叫做记忆化搜索,也叫剪枝(后面我们再细讲)。

所以,如果按照上面的思路将需要计算的部分用数组记录,那么就可以省略那些重复的部分,所以最终我们需要计算的就只剩下以从 1 1 1 n n n 的每个点为起点的最长不下降序列。

以序列 1 , 5 , 2 , 4 , 3 1, 5, 2, 4, 3 1,5,2,4,3 为例:

首先将以每个点为起点的所有长度都初始化为 1 1 1,所有下一步都初始化为 0 0 0

起点下标 起点数值 最长不下降序列的长度 最长不下降序列的起点的下一步的下标
5 5 5 3 3 3 l e n ( 3 ) = 1 len(3)=1 len(3)=1 0 0 0
4 4 4 4 4 4 l e n ( 4 ) = 1 len(4)=1 len(4)=1 0 0 0
3 3 3 2 2 2 l e n ( 2 ) = m a x ( l e n ( 4 ) , l e n ( 3 ) ) + 1 = 2 len(2)=max(len(4), len(3))+1=2 len(2)=max(len(4),len(3))+1=2 4 / 5 4/5 4/5
2 2 2 5 5 5 l e n ( 5 ) = 1 len(5)=1 len(5)=1 0 0 0
1 1 1 1 1 1 l e n ( 1 ) = m a x ( l e n ( 5 ) , l e n ( 2 ) , l e n ( 4 ) , l e n ( 3 ) ) + 1 = 3 len(1)=max(len(5), len(2), len(4), len(3))+1=3 len(1)=max(len(5),len(2),len(4),len(3))+1=3 3 3 3

综上,算法分析

根据动态规划的原理,由后往前进行搜索(当然从前往后也一样)。

  1. b ( n ) b(n) b(n) 来说,由于它是最后一个数,所以当从 b ( n ) b(n) b(n) 开始查找时,只存在长度为 1 1 1 的不下降序列;

  2. 若从 b ( n − 1 ) b(n-1) b(n1) 开始查找,则存在下面的两种可能性:

    ①若 b ( n − 1 ) < b ( n ) b(n-1)b(n1)<b(n) ,则存在长度为 2 2 2 的不下降序列 b ( n − 1 ) b(n-1) b(n1) b ( n ) b(n) b(n)

    ②若 b ( n − 1 ) > b ( n ) b(n-1)>b(n) b(n1)>b(n) ,则存在长度为 1 1 1 的不下降序列 b ( n − 1 ) b(n-1) b(n1) b ( n ) b(n) b(n)

  3. 一般若从 b ( i ) b(i) b(i) 开始,此时最长不下降序列应该按下列方法求出:

    b ( i + 1 ) , b ( i + 2 ) , … , b ( n ) b(i+1),b(i+2),…,b(n) b(i+1),b(i+2),,b(n) 中,找出一个比 b ( i ) b(i) b(i) 大的且最长的不下降序列,作为它的后继。

数据结构

为算法上的需要,定义一个整数类型二维数组 b ( N , 3 ) b(N,3) b(N,3)

  1. b ( i , 1 ) b(i,1) b(i,1) 表示第 i i i 个数的数值本身;
  2. b ( i , 2 ) b(i,2) b(i,2) 表示从 i i i 位置到达 N N N 的最长不下降序列长度;
  3. b ( i , 3 ) b(i,3) b(i,3) 表示从 i i i 位置开始最长不下降序列的下一个位置,若 b [ i , 3 ] = 0 b[i,3]=0 b[i,3]=

你可能感兴趣的:(算法学习,动态规划,代理模式,算法,c++,学习)