LIS优化
LIS(Longest Increasing Subsequence)即最长上升子序列,
如对于 3,1,5,6,2
其LIS为 3(1,5,6)
优秀博客链接:https://blog.csdn.net/zhaohaibo_/article/details/83420145
LIS
dp解决LIS时间复杂度O$(n^2)$
算法思想
- dp[i] 记录a[i]为末尾的上升子序列, 令0<=j < i
- 一重循环i遍历a[],一重循环遍历 a[0]~a[i]
dp[i] = $\begin{cases}1,a[i]<=a[j]\ max(dp[i],dp[j]+1),a[i]>a[j]\end{cases}$
————————————————————代码如下——————————————————————
1 |
|
LIS优化
队列+二分解决LIS时间复杂度O$(n log\ n)$
算法思想
- 队列queue动态存储上升序列,保证queue始终升序
- 一重循环还是i遍历a[i],不同的是
若a[i] 大于队列中最后一个元素,将a[i]加入队尾;
反之,二分查找队列queue中大于a[i]的元素,令a[i]将其替换。 - 最后得到队列的长度即LIS
如对于 3,1,5,6,2 遍历a[i]得到的队列queue依次为:
- 3
- 1
- 1,5
- 1,5,6
- 1,2,6
***注:
记k为序列a[0:i]的最长递增子序列的长度($0\leq i<n$);
queue[k]是序列a[0:i]中所有长度为k的递增子序列中的最小结尾元素值;
可以看到queue[] 并不是动态存放以a[0] ~ a[i]的LIS序列;
而是动态让升序的元素尽可能小,以便后续的更新(解释不下去了,不禁感慨队列优化算法的精妙啊~)
————————————————————代码如下——————————————————————
1 |
|
LIS题目
题目是多组样例,如果不优化O$(n^2)$的时间复杂度妥妥超时;
所以队列+二分真香啊
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!