题解 最长上升子序列 LIS
最长上升子序列 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的更多相关文章
- 2.16 最长递增子序列 LIS
[本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...
- 最长上升子序列LIS(51nod1134)
1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...
- 动态规划(DP),最长递增子序列(LIS)
题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...
- 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】
二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...
- 最长回文子序列LCS,最长递增子序列LIS及相互联系
最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...
- 一个数组求其最长递增子序列(LIS)
一个数组求其最长递增子序列(LIS) 例如数组{3, 1, 4, 2, 3, 9, 4, 6}的LIS是{1, 2, 3, 4, 6},长度为5,假设数组长度为N,求数组的LIS的长度, 需要一个额外 ...
- 1. 线性DP 300. 最长上升子序列 (LIS)
最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...
- 题解报告:poj 2533 Longest Ordered Subsequence(最长上升子序列LIS)
Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence ...
- hdu1025 dp(最长上升子序列LIS)
题意:有一些穷国和一些富国分别排在两条直线上,每个穷国和一个富国之间可以建道路,但是路不能交叉,给出每个穷国和富国的联系,求最多能建多少条路 我一开始在想有点像二分图匹配orz,很快就发现,当我把穷国 ...
随机推荐
- 自然语言处理工具python调用hanlp的方法步骤
Python调用hanlp的方法此前有分享过,本篇文章分享自“逍遥自在017”的博客,个别处有修改,阅读时请注意! 1.首先安装jpype 首先各种坑,jdk和python 版本位数必须一致,我用的是 ...
- GCD and LCM HDU - 4497(质因数分解)
Problem Description Given two positive integers G and L, could you tell me how many solutions of (x, ...
- find_in_set使用
FIND_IN_SET(str,strList) str 要查询的字符串 strList 字段名,参数以“,”分隔,如(1,2,6,8) 查询字段(strList)中包含的结果,返回结果null或记录 ...
- thinkphp命令行生成模型类
thinkphp命令行生成模型类 当你需要创建大量的模型类的时候,不妨考虑下命令行生成,可以快速创建模型类. 在windows下面,使用Win+R输入cmd进入命令控制台,切换到项目根目录(也就是th ...
- 22 Years of KDE
22 Years of KDEhttps://timeline.kde.org/ http://www.kdedevelopers.org/
- lombok 注解
lombok 注解 1. 什么是 lombok 注解 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现 ...
- java实现spark常用算子之Reduce
import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...
- vue项目中实现图片懒加载的方法
对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载.这样子对于页面加载性能上会有很大的提升,也提高了用户体验. 实 ...
- 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结
更多内容:https://www.toutiao.com/i6599796228886626829/?tt_from=weixin&utm_campaign=client_share& ...
- ASP.NET实现验证码图片
新建一个checkcode.aspx文件,页面中不用写任何东西,在代码中,Page_Load中写入如下代码: string chkCode = string.Empty; int ix, ...