LongestIncreasingSubsequence 最长递增子序列

问题

序列ss的递增子序列是原序列的子集,元素相对原序列的顺序不变,且依次递增。例如序列s=[3,0,2,1,4]s = [3,0,2,1,4]的递增子序列有

[],[3],[0],[2],[1],[4],[3,4],[0,2],[0,4],[2,4],[1,4],[0,2,4],[0,1,4][], [3], [0], [2], [1], [4], [3,4], [0,2], [0,4], [2,4], [1,4], [0,2,4], [0,1,4]

求序列ss的最长递增子序列的长度。

解法

设序列ss的长度为nn,范围为[1,n][1,n]。设f(i)f(i)是以s[i]s[i]为最后一个元素的最长递增子序列的长度,则有状态转移方程:

f(i)={0(initialize)i=0max{f(k)+1}(loop)i[1,n],k[1,i1],s[i]>s[k]f(i) = \begin{cases} 0 & (initialize) & i = 0 \\ max \{ f(k)+1 \} & (loop) & i \in [1,n], k \in [1,i-1], s[i] \gt s[k] \end{cases}

(1)(1)00个字符s[0]s[0]的最长递增子序列显然是空的,因此f(0)=0f(0) = 0

(3)(3) 对于序列ss中第ii个数字s[i]s[i],至少s[i]s[i]一个字符可以作为一个递增子序列,因此至少有f(i)1f(i) \geq 1。若s[i]>s[k]s[i] \gt s[k](其中k[1,i1]k \in [1,i-1])则s[i]s[i]s[1,k]s[1,k]的最长递增子序列可以组成一个更长的递增子序列,因此f(i)=f(k)+1f(i) = f(k)+1,遍历所有可能的kk,找出下一个最长的递增子序列;

该算法的时间复杂度为O(n2)O(n^2)

源码

LongestIncreasingSubsequence.h

LongestIncreasingSubsequence.cpp

测试

LongestIncreasingSubsequenceTest.cpp

Last updated