最长上升子序列问题【LIS】

· · 个人记录

对于给定序列A,要求最长子序列M,使得M中的元素单调递增

常规做法时间复杂度为O(n^{2}),较简单,不多赘述。

这里记录的是本问题的贪心解,时间复杂度O(nlogn)

我们引入序列q

![q序列](https://cdn.acwing.com/media/article/image/2021/03/17/1301_01893de287-LIS-2.jpg) 贪心思路:较小的数开头的数作为的子序列 比 较大的数作为开头的子序列 更好 贪心步骤: 1. 开一个数组q[i],存的是以长度为i的上升子序列中末尾元素最小的数 2. q[]一开始是空集,长度为0 3. 遍历每个数x,对于当前数x, 先找到一个最大的小于x的数c: - 情况1:若找不到c, 扩大q[]的长度并记录当前数x - 情况2:若找到c, 就存在一个不等式c < x ≤ a < b, 则将x覆盖a的位置 ```cpp int tt = 0; q[0] = -1; for(int i = 1; i <= n; i ++){ int l = 0, r = tt; while (l < r){ int mid = l + r + 1 >> 1; if(a[i] > q[mid]) l = mid; else r = mid - 1; } q[r + 1] = a[i]; tt = max(tt, r + 1); } ```