最长上升子序列 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算法就忽略了,这两个太容易理解了. 假设存在一个 ...
随机推荐
- 2022春每日一题:Day 11
题目:高斯消元法 高斯消元法是一个模板,下面简单介绍其内容以及实现方法. 高斯消元是求一个求多元一次方程组的解的算法. 就是形式如下的关于x1,x2...xn的方程组的解. a11x1 + a12x2 ...
- vue脚手架安装及依赖
一.安装Vue Cil (脚手架) 需要先安装node.js,这是node官网地址: https://nodejs.org/en/download/ ,node有两种版本一种是稳定版一种开发版 安装完 ...
- 微服务---Dubbo+Zookeeper
dubboAdmin客户端 --监控 && 启动 Zookeeper 客户端 --注册中心 生产者: <?xml version="1.0" encoding ...
- 斐波那契散列算法和hashMap实践
斐波那契散列和hashMap实践 适合的场景:抽奖(游戏.轮盘.活动促销等等) 如果有不对的地方,欢迎指正! HashMap实现数据散列: 配置项目,引入pom.xml: <dependency ...
- 关于linux上strongswan客户端的配置
前言 这几天回家了,想连学校的vpn, 学校vpn用的是strongswan的EAP认证(不需要证书什么的),手机上直接用软件连接就可以了,windows也是内置了这个协议,无奈我用的是linux m ...
- Go | 闭包的使用
闭包基本介绍 闭包就是 一个函数 和其相关的 引用环境 组合的一个整体 好处: 保存引用的变量,下次继续使用,不会销毁 下面通过闭包的方式,写一个数字累加器,体验一下闭包的妙处 闭包实现数字累加 pa ...
- apache文件工具类的使用:org.apache.commons.io.FileUtils
说明 org.apache.commons.io.FileUtils 工具类包含了许多操作文件的方法,此文章介绍一些常用的文件操作方法,方便使用的时候查阅参考 创建输入流 public static ...
- JavaScript入门⑧-事件总结大全
JavaScript入门系列目录 JavaScript入门①-基础知识筑基 JavaScript入门②-函数(1)基础{浅出} JavaScript入门③-函数(2)原理{深入}执行上下文 JavaS ...
- 粘包、struct模块、进程并行与并发
目录 粘包现象 struct模块 粘包代码实战 udp协议(了解) 并发编程理论 多道技术 进程理论 进程并行与并发 进程的三状态 粘包现象 1.服务端连续执行三次recv 2.客户端连续执行三次se ...
- 修改数据时,一直提示"具有 XXX 的 字典管理 已存在(即数据已存在)
原代码: class DictConfig(models.Model): """ 字典表 """ id = models.AutoField ...