出自蓝书《算法竞赛入门经典训练指南》

求最长上升子序列是很常见的可以用动态规划解决的问题……

很容易根据最优子结构之类的东西得出

$\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)算法的更多相关文章

  1. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  2. 最长上升子序列(LIS)长度的O(nlogn)算法

    最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...

  3. 最长递增子序列 O(NlogN)算法

    转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...

  4. 最长不下降子序列的O(n^2)算法和O(nlogn)算法

    一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...

  5. 最长上升子序列O(nlogn)算法详解

    最长上升子序列 时间限制: 10 Sec   内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...

  6. 连续子序列最大和的O(NlogN)算法

    对于一个数组,例如:int[] a = {4,-3,5,-2,-1,2,6,-2}找出一个连续子序列,对于任意的i和j,使得a[i]+a[i+1]+a[i+2]+.......+a[j]他的和是所有子 ...

  7. 浅析拯救小矮人的 nlogn 算法及其证明

    浅析拯救小矮人的 nlogn 算法及其证明 题型简介: 有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯. ...

  8. 最长上升子序列(LIS)n2 nlogn算法解析

    题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...

  9. hdu 1950 最长上升子序列(lis) nlogn算法【dp】

    这个博客说的已经很好了.http://blog.csdn.net/shuangde800/article/details/7474903 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...

随机推荐

  1. CSS Grid 布局完全指南(图解 Grid 详细教程)

    CSS Grid 布局是 CSS 中最强大的布局系统.与 flexbox 的一维布局系统不同,CSS Grid 布局是一个二维布局系统,也就意味着它可以同时处理列和行.通过将 CSS 规则应用于 父元 ...

  2. arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  3. [翻译] Oracle Database 12c 新特性Multitenant

    译自官方白皮书http://www.oracle.com/technetwork/database/plug-into-cloud-wp-12c-1896100.pdf,包含新的云计算相关技术的介绍. ...

  4. 使用python操作XML增删改查

    使用python操作XML增删改查 什么是XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输 ...

  5. IPD体系向敏捷开发模式转型实施成功的四个关键因素

    文/杨学明  集成产品开发(IPD).集成能力成熟度模型(CMMI).敏捷开发(Agile Development)是当前国内外企业产品研发管理的最常用的3种模式.随着创新环境的快速发展,许多企业都会 ...

  6. 在coding或者github建立个人站点域名绑定

    coding:静态的在域名服务器与是填写pages.coding.me,不是填写{你的名字}.coding.me A型的ip是ping 该域名ip github:上传大项目可能报错(报错名字忘记了), ...

  7. 我的第一个python web开发框架(32)——定制ORM(八)

    写到这里,基本的ORM功能就完成了,不知大家有没有发现,这个ORM每个方法都是在with中执行的,也就是说每个方法都是一个完整的事务,当它执行完成以后也会将事务提交,那么如果我们想要进行一个复杂的事务 ...

  8. sqlalchemy外键的一些东西

    sqlalchemy中让MySQL支持中文字符 engine = create_engine("mysql+pymysql://root:mysql8@localhost/mysqltest ...

  9. 【English】20190416

     anti-money laundering反洗钱[ˈænti][ˈlɔːndərɪŋ] misconduct不当行为[ˌmɪsˈkɑːndʌkt]   Currently, she is focus ...

  10. Git命令行管理代码、安装及使用

    出处:https://www.cnblogs.com/ximiaomiao/p/7140456.html Git安装和使用     目的:通过Git管理github托管项目代码 一.下载安装Git 1 ...