LIS的O(nlogn)算法
出自蓝书《算法竞赛入门经典训练指南》
求最长上升子序列是很常见的可以用动态规划解决的问题……
很容易根据最优子结构之类的东西得出
$\text{dp}[i]$为以第i个数结尾的最长上升子序列长度
定义$\max{\emptyset}=0$,粗略地写出
\[\text{dp}[i] = \max \left\{ \text{dp}[j]|0\leqslant j < i,A[j] < A[i] \right\} + 1\]
状态数$\mathcal{O}({n})$,如果直接枚举转移,转移数$\mathcal{O}({n})$,时间复杂度$\mathcal{O}({n^2})$
现在想办法加速转移……
设$\text{dp}^{-1}[x]$为$x=\text{dp}[i]$中$\text{A}[i]$最小的$i$
设$\text{pd}[x]=\text{A}[\text{dp}^{-1}[x]]$
若有$\text{A}[i]<\text{A}[j]$且$\text{dp}[i]==\text{dp}[j]$,那么之后的元素只需要比$\text{A}[i]=\text{pd}[x]=\text{pd}[\text{dp}[i]]$大就可以用$\text{dp}[i]$进行转移
很容易得\[\text{pd}[1]\leqslant \text{pd}[2]\leqslant \text{pd}[3]\leqslant \cdots \leqslant \text{pd}[n] \tag{1}\label{1} \]
\[\text{dp}[i]=\max\left\{x|0\leqslant j < i,\text{pd}[x]<A[i]\right\}+1\]
即最大的小于A[i]的下标加1,也就等价于最小的大于等于A[i]的下标,设为$k$ $\tag{2}\label{2}$

因为最后$[l,r)$区间收缩到$\emptyset$时左侧区间最后一个元素加一就是右侧区间第一个元素
用STL的lower_bound就不需要自己写二分了
因为$\eqref{1}\eqref{2}$,所以$A[i]\leqslant \text{pd}[k]$,转移以后需要更新$\text{pd}[k]$
但是之前少考虑了$0\leqslant j < i$,只需将未计算的$\text{pd}[x]$设为INF就好了= =
时间复杂度$\mathcal{O}(n\log n)$
代码
REPE(i,1,n) pd[i]=INF;
REP(i,0,n) {
int k=lower_bound(pd+1,pd+1+n,A[i])-g;
dp[i]=k;
pd[k]=A[i];
}
很容易得最长非降子序列只需将lower_bound改为upper_bound(同样照着二分的参考图)
然后最长下降子序列只需添加greater<int>()参数,并且初始化为-INF
注意dp为以第i个数结尾的长度,所以求最长还需求一遍max
LIS的O(nlogn)算法的更多相关文章
- POJ 1631 Bridging signals(LIS O(nlogn)算法)
Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...
- 最长上升子序列(LIS)长度的O(nlogn)算法
最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
- 最长不下降子序列的O(n^2)算法和O(nlogn)算法
一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...
- 最长上升子序列O(nlogn)算法详解
最长上升子序列 时间限制: 10 Sec 内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...
- 连续子序列最大和的O(NlogN)算法
对于一个数组,例如:int[] a = {4,-3,5,-2,-1,2,6,-2}找出一个连续子序列,对于任意的i和j,使得a[i]+a[i+1]+a[i+2]+.......+a[j]他的和是所有子 ...
- 浅析拯救小矮人的 nlogn 算法及其证明
浅析拯救小矮人的 nlogn 算法及其证明 题型简介: 有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯. ...
- 最长上升子序列(LIS)n2 nlogn算法解析
题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...
- hdu 1950 最长上升子序列(lis) nlogn算法【dp】
这个博客说的已经很好了.http://blog.csdn.net/shuangde800/article/details/7474903 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...
随机推荐
- JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript 之间转换
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 15 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- 【代码笔记】Web-CSS-CSS 分组和嵌套
一, 效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- Jetty 开发指南:Jetty 内嵌开发
Jetty的口号是“不要在Jetty中部署你的应用程序,在你的应用程序中部署Jetty!” 这意味着,作为将应用程序捆绑为要部署在Jetty中的标准WAR的替代方案,Jetty旨在成为一个软件组件,可 ...
- SAP MM MIGO & Return Delivery 组合实现部分数量的Reversal
SAP MM MIGO & Return Delivery 组合实现部分数量的Reversal 在笔者看来,MIGO这个事务代码里的Return Delivery主要用于采购退货场景. 先找到 ...
- Mapbox浅析(快速入门Mapbox)
1.是什么? Mapbox是一个可以免费创建并定制个性化地图的网站. 2.了解一些基本东西 常见的 mapbox.js和mapbox-gl.js的异同点? 相同点: 1.都是由Mapbox公司推出的免 ...
- Python开发爬虫之理论篇
爬虫简介 爬虫:一段自动抓取互联网信息的程序. 什么意思呢? 互联网是由各种各样的网页组成.每一个网页对应一个URL,而URL的页面上又有很多指向其他页面的URL.这种URL之间相互的指向关系就形成了 ...
- Android 中使用 dlib+opencv 实现动态人脸检测
1 概述 完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo.该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用 ...
- java设计模式——适配器模式 Java源代码
前言:适配器模式就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作.通常被用在一个项目需要引用一些开源框架来一起工作时,这些框架的内部都有一 ...
- 【笔记】两个根因分析方法:5WHY&10WHY
什么是问题根因分析 根本原因分析(root cause analysis):通过调查和分析问题哪里出错.为什么出错,寻求防止差错事故再次发生的必要措施,从而提高服务安全和质量. 根因分析目标 问题(发 ...
- 用 Weave Scope 监控集群 - 每天5分钟玩转 Docker 容器技术(175)
创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kubernetes 是一个复杂系统,运维团 ...