最长单调子序列问题(Longest increasing subsequence)

来源:互联网 发布:sqlite数据库下载 编辑:程序博客网 时间:2024/06/05 17:56

给定一个长度为n的数组a[0...n-1]。

    (1)如果存在0 <= i1 < i2 < ... < ik < n,使得的a[i1] <= a[i2] <= ... <= a[ik],则称a[i1],a[i2]...a[ik]是数组a的一个长度为k的单调上升子序列
    (2)如果存在0 <= i1 < i2 < ... < ik < n,使得的a[i1] >= a[i2] >= ... >= a[ik],则称a[i1],a[i2]...a[ik]是数组a的一个长度为k的单调下降子序列
    (3)如果存在0 <= i1 < i2 < ... < ik < n,使得的a[i1] < a[i2] < ... < a[ik],则称a[i1],a[i2]...a[ik]是数组a的一个长度为k的严格单调上升子序列
    (4)如果存在0 <= i1 < i2 < ... < ik < n,使得的a[i1] > a[i2] > ... > a[ik],则称a[i1],a[i2]...a[ik]是数组a的一个长度为k的严格单调下降子序列

最长单调子序列问题即求最长的(严格)单调上升/下降子序列。以下以最长单调上升子序列为例,其他类同。



用LIS[i]表示[0,i]之间以a[i]为最长单调上升子序列最后一项的长度,ANS[i]表示[0,i]之间最长单调上升子序列的长度,则显然有:

ANS[i] = max{ LIS[k] | 0 <= k < i } = max { ANS[i-1],LIS[i] }

LIS[i] = 1 + min { LIS[k] | 0 <= k < i,且a[k] <= a[i] }

根据这两个个状态关系式,显然存在一个O(n^2)的算法,并且ANS[0...n-1]可以优化只用一个变量表示。


MINLIS[i]表示所有长度为i的单调上升子序列的最后一项值的最小值,显然MINLIS[i-1] <= MINLIS[i],即MINLIS是一个递增的序列

如果存在k,使得MINLIS[k] <= data[i] < MINLIS[k+1],那么LIS[i] = k + 1;MINLIS[k+1] = data[i]

由于MINLIS有序,因此可以二分,即存在一个O(nlogn)的算法,并且LIS[0...n-1]可以优化掉

0 0