最长上升子序列 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. SQL server 维护计划中 “清除维护任务” 执行报错

    SQL server 维护计划中 “清除维护任务” 执行报错,错误如下: 执行查询“EXECUTE master.dbo.xp_delete_file 0,N'',N'',N'2019...”失败,错 ...

  2. mysql语句(一)

    --建表CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` ...

  3. Nginx整合Tomcat

    现在先不考虑集群的配置问题,只实现Nginx实现一台tomact的代理 1.我们需要一个web项目,这里我把先准备好的web.war文件部署到Tomact服务器上 mvn clean install ...

  4. Spring4学习回顾之路08- FactoryBean配置Bean

    建立Student.java package com.lql.srping04; /** * @author: lql * @date: 2019.10.28 * Description: */ pu ...

  5. appium-Android_webview页面元素定位遇到的问题

    如上图所示,该页面包含webview,但是用driver.contexts只获取到了Android原生,而webview的context则没有获取到,所以webview页面的元素.希望有大佬能提供有效 ...

  6. Codeforces 1244D. Paint the Tree

    传送门 首先如果某个点的度数大于 $2$ 那么显然无解 然后考虑点的度数小于等于 $2$ 的情况 发现其实是一条链 一旦确定了链开头的两个点,后面的点的颜色都可以通过之前的点推出 所以直接枚举即可 # ...

  7. 美团2017年CodeM大赛-初赛B轮 黑白树 (树形dp)

    大意: 给定树, 初始每个点全为白色, 点$i$有权值$k_i$, 表示选择$i$后, 所有距离$i$小于$k_i$的祖先(包括i)会变为黑色, 求最少选多少个点能使所有点变为黑色. 链上情况的话, ...

  8. Java EE javax.servlet ServletContainerInitializer接口

    ServletContainerInitializer接口 public interface ServletContainerInitializer 一.介绍 该接口,允许在 web 应用程序的启动阶 ...

  9. C#面向对象14 List泛型集合/装箱和拆箱/字典集合(Dictionary)

    1.List泛型集合 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...

  10. Linux Permission denied 问题

    Linux Permission denied 问题 来源  https://www.cnblogs.com/sparkdev/p/10287164.html 如果当前用户没有某个文件的写权限,又要通 ...