[基本思路]最长上升子序列
基本题意
给出一个长度为 \(N\) 的整数序列,求出包含第 \(k\) 个数的最长上升子序列。
- 对于\(25\%\)的数据,\(N\leq 5000\)
- 对于\(100\%\)的数据,\(N\leq 200000\)
基本思路
\(25\)分做法
可以转化一下题目:求出以 \(k\) 结尾的最长子序列长度,以 \(k\) 开头的最长子序列长度,再减去 \(1\)(\(k\) 本身算了 \(2\) 遍)
定义 \(dp[i]\) 表示以 \(i\) 结尾的最长上升子序列长度。
定义 \(dp1[i]\) 表示以 \(i\) 开头的最长上升子序列长度。
以 \(i\) 结尾就是普通模板,以 \(i\) 开头倒序求一遍即可。
复杂度:\(O(N^2)\)。
\(100\)分做法
众所周知,求最长上升子序列有 \(O(n\log n)\) 解法。
为了方便,可以按照以下思路进行:
- 找出前 \(k-1\) 个数当中小于第 \(k\) 个数的数,保存至 \(b\) 数组里
- 把第 \(k\) 个数保存至 \(b\) 数组里
- 找出 \(k+1\) 至 \(n\) 当中大于第 \(k\) 个数的数,保存至 \(b\) 数组里
然后对 \(b\) 数组求一遍最长上升子序列完事了!
总结
对于这种题目,要分析本质东西,比如这道题他包含第 \(k\) 个数的 LIS 那么 \(k\) 前面的一定比 \(k\) 小,\(k\) 后面的一定比 \(k\) 大。
另附求 LIS 极简代码:code