最长上升子序列 II 时间复杂度(nlogn)
题目:最长上升子序列 II
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤100000,
−10e9≤数列中的数≤10e9
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
问题解决
这个问题我用dp+二分法的方法来写。
一、 遍历a[i]将a[i]放入dp数组
1.1构造dp[i]数组:
dp[i]为长度是i的上升子序列结尾元素。
i:表示子序列的长度,取值范围是1~len,其中len表示目前最大的子序列长度。
1.2 将a[i]放入dp数组中
规则为找到某个dp[j],使得a[i]>dp[j]&&a[i]<dp[j+1],
找到后将dp[j+1]替换为a[i],更新len 判断len是否因dp数组的扩大而变大,len=max(len,j+1)。
...........................................................................................................................................................................................................
二 、在dp[1]和dp[len]之间寻找满足1.2条的位置
2.1 L端起点和r端终点的初始选择
因为dp[i]的取值范围是1~len所以起始边界设置在两端之外L=0,r=len+1;
2.2 退出二分的条件
当L+1==r时说明两个指针已经相邻,边界已经找到即可退出循环。
2.3 L端和r端分界线的判定条件
L端都<a[i],r端都>=a[i],满足l端条件L=mid,否则r=mid。
2.4 采用r
r即为1.2中的j+1。
我用的是手写二分法,主要参考链接如下:
https://www.bilibili.com/video/BV1d54y1q7k7?from=search&seid=14378360076371462119
大家也可以用upper_bound来取得r值。
3 总结
该程序时间复杂度为O(n*log n),可以解决n=1e5的规模的问题。
程序君:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
const int inf=1e9;
int main()
{
int a[N],dp[N],n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int len=0;
for(int i=1;i<=n;i++)
{
int l=0,r=len+1;
while(l+1!=r)
{
int m=l+r>>1;
if(dp[m]<a[i])
{
l=m;
}
else
{
r=m;
}
}
dp[r]=a[i];
len=max(len,r);
}
cout<<len;
return 0;
}
最长上升子序列 II 时间复杂度(nlogn)的更多相关文章
- 最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现
关于最长递增子序列时间复杂度O(n^2)的实现方法在博客http://blog.csdn.net/iniegang/article/details/47379873(最长递增子序列 Java实现)中已 ...
- HDU 5748 最长上升子序列的长度nlogn(固定尾部)
Bellovin Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- 最长上升子序列(LIS)n2 nlogn算法解析
题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...
- AcWing 896. 最长上升子序列 II
#include<iostream> #include<algorithm> #include<vector> using namespace std; int m ...
- 最长上升子序列O(nlogn) 要强的T^T(2358)
题目来源:http://www.fjutacm.com/Problem.jsp?pid=2358 要强的T^T TimeLimit:1000MS MemoryLimit:65536K 64-bit ...
- BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告
这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这 ...
- [ An Ac a Day ^_^ ] HDU 1257 基础dp 最长上升子序列
最近两天在迎新 看来只能接着水题了…… 新生培训的任务分配 作为一个有担当的学长 自觉去选了动态规划…… 然后我觉得我可以开始水动态规划了…… 今天水一发最长上升子序列…… kuangbin有nlog ...
- LIS最长上升子序列O(n^2)与O(nlogn)的算法
动态规划 最长上升子序列问题(LIS).给定n个整数,按从左到右的顺序选出尽量多的整数,组成一个上升子序列(子序列可以理解为:删除0个或多个数,其他数的顺序不变).例如序列1, 6, 2, 3, 7, ...
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
随机推荐
- SpringBoot yml配置文件中,logging.level报错
报错 *************************** APPLICATION FAILED TO START *************************** Description: ...
- minio API demo
package mainimport ( "context" "fmt" "github.com/minio/minio-go/v7" &q ...
- 【Java 并发003】原理层面:Java并发三特性全解析
一.前言 不管什么语言,并发的编程都是在高级的部分,因为并发的涉及的知识太广,不单单是操作系统的知识,还有计算机的组成的知识等等.说到底,这些年硬件的不断的发展,但是一直有一个核心的矛盾在:CPU.内 ...
- 再见CMS
观察网站最下方,根据备案号搜到这是个齐博CMS,然后百度就可以搜到齐博CMS漏洞了 然后开始利用 首先尝试了在用户信息修改处进行注入,发现好像想不通了,就在博客界面进行注入 Payload: 获取版本 ...
- 【Java EE】Day09 JavaScript基础
一.JavaScript简介 二.JavaScript语法 三.JavaScript对象
- UBOOT 启动流程
一.概述 uboot 的启动流程在网上有很多大佬记录,但是了对于像我这样的新手就有些困难了,而我也不做 uboot 相关的工作,所以没必去研究代码,这里我特意整理了一下,以流程图的形式展现代码执行的流 ...
- PAM8403 3.3V音频功放调试笔记
做I2S输出用了PT8211(实际上买到的丝印是GH8211), 双声道, LSB格式, 工作正常但是输出功率非常低, 喇叭声音要贴近了才能勉强听到, 所以打算做一个PT8211带功放的I2S模块. ...
- 搭建IIS网站后,点击浏览地址,报403错误
点击左侧的浏览地址,报右侧的错误,可将目录浏览进行启用 双击进去,进行启用即可
- 使用命令行运行用例时提示python.exe: Error while finding module specification for 'testcase_1.Test'.....
文件路径 输入命令 D:\demo>python -m unittest unittest_1/testcase_1.Test结果提示 ModuleNotFoundError: No modul ...
- python 之excel文件读取封装
import os import xlrd PATH = lambda p: os.path.abspath( os.path.join(os.path.dirname(__file__), p) ) ...