最长上升子序列 LIS

Description

给出一个 1 ∼ n (n ≤ 10^5) 的排列 P

求其最长上升子序列长度

Input

第一行一个正整数n,表示序列中整数个数;

第二行是空格隔开的n个整数组成的序列。

Output

最长上升子序列的长度

Sample Input

7

1 7 3 5 9 4 8

Sample Output

4

解析

这题\(O\)(\(n^2\))很容易就能想到,

然而,\(1e5\)却会炸掉....

所以,考虑二分.

我们维护一个类似于栈的数组\(q\)(其实是序列但为了方便懒得打字后面就称作栈吧)

令\(q[i]\)表示长度为\(i\)的序列的最后一个元素,

那么,从\(1\)~\(n\)枚举,每次在\(q\)中寻找第一个大于等于\(a[i]\)(即权值)的元素,

再用\(a[i]\)去更新它,并且它的下标就是以\(a[i]\)结尾的最长上升子序列.

而原因也很简单,对于\(i\)后面的元素\(k\)以及\(i\)更新掉的元素\(j\),

首先,根据算法,我们知道\(a[i]\)<=\(a[j]\),且以\(a[i]\)结尾的上升子序列长度等于以\(a[j]\)结尾的上升子序列长度.

那么,对于\(k\),它接到\(i\)后面和接到\(j\)后面的效果(即长度)是一样的,

但是,如果\(a[i]\)<\(a[k]\)<\(a[j]\),那么\(k\)能接到\(i\)后面,却不能接到\(j\)后面,

所以,用\(i\)更新掉\(j\)一定是更优的,

并且,\(j\)的长度也是对于\(i\)来说最优的,

因为后面的接不上了.

于是最后,再从\(1\)~\(n\)扫一遍,取最大值就行了.

口胡证明自己理解下哈

上代码吧:

#include<bits/stdc++.h>
using namespace std; inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
} int n,a[100001],ans=0;
int f[100001],c[100001]; int main(){
n=read();
memset(c,0x3f,sizeof(c));
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++){
int k=lower_bound(c+1,c+n+1,a[i])-c;
f[i]=k;c[k]=a[i];
}
for(int i=1;i<=n;i++) ans=max(ans,f[i]);
printf("%d\n",ans);
return 0;
}

题解 最长上升子序列 LIS的更多相关文章

  1. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  2. 最长上升子序列LIS(51nod1134)

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...

  3. 动态规划(DP),最长递增子序列(LIS)

    题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...

  4. 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】

    二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...

  5. 最长回文子序列LCS,最长递增子序列LIS及相互联系

    最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...

  6. 一个数组求其最长递增子序列(LIS)

    一个数组求其最长递增子序列(LIS) 例如数组{3, 1, 4, 2, 3, 9, 4, 6}的LIS是{1, 2, 3, 4, 6},长度为5,假设数组长度为N,求数组的LIS的长度, 需要一个额外 ...

  7. 1. 线性DP 300. 最长上升子序列 (LIS)

    最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...

  8. 题解报告:poj 2533 Longest Ordered Subsequence(最长上升子序列LIS)

    Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence ...

  9. hdu1025 dp(最长上升子序列LIS)

    题意:有一些穷国和一些富国分别排在两条直线上,每个穷国和一个富国之间可以建道路,但是路不能交叉,给出每个穷国和富国的联系,求最多能建多少条路 我一开始在想有点像二分图匹配orz,很快就发现,当我把穷国 ...

随机推荐

  1. Redis(1.9)Redis主从复制

    [1]实验环境 CentOS7.5 + Redis4.0.11 架构:原生1主2从,做实验机器有限,从库双实例 主库:192.168.135.170 从库1:192.168.135.171~6379 ...

  2. Analyzing Polyline -- Codeforces Round #123 (Div. 2)

    题意:https://codeforc.es/problemset/problem/195/D 求折线段数. 思路: 对pos进行sort,对不同区间段加k,两个dp处理不同k>0 or k&l ...

  3. Sentinal LDK 加密狗的使用

    公司的软件用了第三方的加密key,在代码里只是用了其中的一个功能:GetKeyInfo()判断电脑是否有插入u盾.现做简单的说明如下: 第一步.插入master key 到电脑,下载正式的hvc 授权 ...

  4. crm--rbac权限组件使用步骤

    本人的权限组件码云地址:https://gitee.com/shiguanggege/rbac 里面有文档详细介绍权限组件的使用步骤

  5. h5中的分组元素figure、figcaption、hgroup元素介绍

    分组元素用于对页面中的内容进行分组. figure元素和figcaption元素 figure元素用于定义独立的流内容(图像.图表.照片.代码等),一般指一个独立的单元.figure元素的内容应该与主 ...

  6. flask数据库迁移

    实际操作顺序:1.python 文件 db init2.python 文件 db migrate -m"版本名(注释)"3.python 文件 db upgrade 然后观察表结构 ...

  7. Jmeter之压测探索和结果分析

    1.copy过来的,很有道理的一句话~ 最大并发数:取决于你的业务类型,数据量,处理时的资源需求等,具体多少,需要做一些性能测试来衡量 确定待测试的场景,设计脚本,不断增加并发数量. 2.CPU压不上 ...

  8. X86逆向2:提取按钮通杀特征码

    本章我们将学习特征码的提取与定位,特征码是软件中一段固定的具有标志性的代码片段,特征码的用途非常广泛,最常见的就是杀毒软件的查杀了,查杀就是根据特征码定位技术实现的,再比如木马的免杀也是修改了特征码的 ...

  9. Cannot call sendRedirect() after the response has been committed的解决办法

    做一个Login Demo的时候,写了如下代码: protected void doPost(HttpServletRequest request, HttpServletResponse respo ...

  10. 你不知道的css各类布局(二)之流体布局、液体布局、栅格布局

    流体布局 什么是流 在谈论流体布局之前我们需要知道一件事情就是何为“流”,所谓“流”就是“文档流”,是css中的一种基本定位和布局 概念 流体布局(Liquid/Fluid Layout)指的是利用元 ...