📜  门| GATE-CS-2000 |问题 37(1)

📅  最后修改于: 2023-12-03 15:42:14.837000             🧑  作者: Mango

题目

门| GATE-CS-2000 | 问题 37

题目描述

给定n(n>1)个整数a1,a2,…,an,其中每个整数的范围是1n(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数组为空。
  • 从前往后遍历数组,对于每个$a_i$,选出满足$a_i>a_j$的所有$j$,计算dp[i],并更新其前驱元素pre[i] = j
  • 最后在dp中选出最大值maxLength,记录其位置pos,然后倒序输出从pos开始的元素,直到前驱元素为空(表示已到达LIS的开始)。