题解 最长上升子序列 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,很快就发现,当我把穷国 ...
随机推荐
- 【LOJ】#3032. 「JOISC 2019 Day1」馕
LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...
- Snoopy.class.php使用手册
Snoopy - the PHP net client v1.2.4 Snoopy是一个php类,用来模拟浏览器的功能,可以获取网页内容,发送表单.Snoopy的特点:1.抓取网页的内容 fetch2 ...
- HTML accessKey约定俗成的标准
accessKey属性提供了键盘快捷键 例: <a href="index.html" accessKey="1">Home</a> 这 ...
- 【动态规划】subsequence 1
题目链接:https://ac.nowcoder.com/acm/contest/885/G 题意: 两个串,s t,求s的所有子串中大于 t 的数目 题解: dp[i][j] 表示 s的前i个, ...
- 怎样理解 Vue 中的计算属性 computed 和 methods ?
需求: 在 Vue 中, 我们可以像下面这样通过在 引号 或 双花括号 内写 js 表达式去做一些简单运算, 这是可以的, 不过这样写是不直观的, 而且在 html 中 夹杂 一些运算逻辑这种做法其实 ...
- GTA4 EFLC cheat code
GTA4 EFLC cheat code 提示警告:您的图像设置接近或超出您的系统推荐资源限制,为了使游戏运行更加流畅推荐你降低你的图像设置. 在游戏目录新建名为 commandline的txt文本文 ...
- java面试6
1.Redis是单线程还是多线程?为什么能支持访问量和高并发?并举例解释? 1)Redis是单线程的 2)Redis是单线程加多路IO复用 3)例子:上课老师解决同学们的提问 2.Nginx有哪些基本 ...
- Entity Framework:三种开发模式实现数据访问
原文地址 http://blog.csdn.net/syaguang2006/article/details/19606715 前言 Entity Framework支持Database First. ...
- Redis-String常用命令
Redis-String常用命令 set key value- 设置Key-value键值对 get key 获取指定key对应的值 append key value 在指定key对应值的后面追加va ...
- OGG学习笔记02
实验环境:源端:192.168.1.30,Oracle 10.2.0.5 单实例目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1.模拟源数据库业务持续运行 2.配置OGG前 ...