📅  最后修改于: 2023-12-03 15:42:14.837000             🧑  作者: Mango
门| GATE-CS-2000 | 问题 37
给定n(n>1)
个整数a1,a2,…,an
,其中每个整数的范围是1
到n(n\leq200)
。现在定义以下概念:
b
是序列a
的子序列当且仅当b
可以由a
中删除任意数量的元素但不改变其余元素的相对位置得到。b
被称为a
的LIS (最长递增子序列) ,当且仅当b
是递增序列并且没有更长的递增子序列。例如,arthrakshastra
的长度为3
,因为a1,a3,a4
组成一个递增序列。
现在给定a
,设计一个算法,找出一个a
的LIS,并且你的算法的最坏情况时间复杂度应该是O(n^2)
。
输入:
6
1 4 2 5 3 6
输出:
4
解释:
a
的一个LIS是1,2,3,6
。
这是一道比较经典的动态规划问题,类似于“最长公共子序列”问题。定义dp[i]
表示以第i
个数为结尾的最长递增子序列的长度,则有:
$$dp[i] = max_{j<i}(dp[j]+1)$$
其中,$j$满足$a_i>a_j$。
显然,时间复杂度为$O(n^2)$。为了输出LIS序列,我们还需要额外维护一个pre
数组,记录每个位置的前驱元素。
算法思路如下:
dp
为1,pre
数组为空。dp[i]
,并更新其前驱元素pre[i] = j
。dp
中选出最大值maxLength
,记录其位置pos
,然后倒序输出从pos
开始的元素,直到前驱元素为空(表示已到达LIS的开始)。