最长上升子序列(LIS)n2 nlogn算法解析
题目描述
给定一个数列,包含N个整数,求这个序列的最长上升子序列。
例如 2 5 3 4 1 7 6 最长上升子序列为 4.
1.O(n2)算法解析
看到这个题,大家的直觉肯定都是要用动态规划来做,那么我们先设立一个数组。
设d[ i ]为以a[ i ]为结尾的最大子序列的长度
有了这个后,我们可以很容易的写出状态转移方程:
d[ i ] = max(d[ i ] , d[ j ] + 1) 若 j < i 且 a[ i ] > a[ j ]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 1000
int d[N];//表示以a[i]结尾的最大长度
int a[N];
int main() {
for (int i = 0; i < 7; i++) {
cin >> a[i];
}
d[0] = 1;
for (int i = 1; i < 7; i++) {
d[i] = 1;
for (int j = 0; j < i; j++) {
if (a[i] > a[j])
d[i] = max(d[j] + 1, d[i]);
}
}
int maxt = -1;
for (int i = 0; i < 7; i++) {
maxt = max(d[i], maxt);
}
cout << maxt << endl;
return 0;
}
2.O(ologn)算法解析
首先我们给数组d换一种含义,设d[ i ] 为 长度为 i 的子序列的最后一个元素的值。
我们要做的就是,依次把每一个元素插到他合适的位置上去。
例如现在的数组d为
这时我们要处理一个元素,假设值为5,那我们应该放到哪里?
这里面长度为2的子序列最后一个长度为4,5>4,因此我们可以把5放到d[3]中。
但是把6换成5有什么意义呢?
显然,序列元素有限的情况下,子序列的末尾元素越小,越有利于我们向后添加元素(增大其长度)。
这句话就是解决问题的关键。
因此,处理每一个元素的时候,我们只需要把元素填入第一个大于这个元素值的d[ i ]中就好。
通过简单的分析,我们很容易知道数组d是个递增的数组,因此解决上面这个问题,我们采用二分查找,写一个find()函数,返回第一个大于该元素值 t 的数组d元素的下标。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 1000
int d[N];
int a[N];
int find(int l, int r, int x) {//寻找数组d中第一个大于x的元素的下标
while (l <= r) {
int mid = (l + r) / 2;
if (d[mid] < x) {
l = mid + 1;
}
else {
r = mid - 1;
}
}
return l;
}
int main() {
for (int i = 0; i < 7; i++) {
cin >> a[i];
}
d[0] = -0x3f3f3f3f;
int len = 1;
for (int i = 1; i < 7; i++) {
if (a[i] > d[len]) {
d[++len] = a[i];
}
else {
int k = find(1, len, a[i]);
d[k] = a[i];
}
}
cout << len;
return 0;
}
最长上升子序列(LIS)n2 nlogn算法解析的更多相关文章
- 最长上升子序列LIS(51nod1134)
1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...
- lrj 9.4.1 最长上升子序列 LIS
p275 d(i)是以Ai为结尾的最长上升子序列的长度 <算法竞赛入门经典-训练指南>p62 问题6 提供了一种优化到 O(nlogn)的方法. 文本中用g(i)表示d值为i的最小状态编号 ...
- 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】
二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...
- 题解 最长上升子序列 LIS
最长上升子序列 LIS Description 给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的 ...
- 最长回文子序列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的长度, 需要一个额外 ...
- 浅谈最长上升子序列(O(n*logn)算法)
今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...
- 2.16 最长递增子序列 LIS
[本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...
- LCS(最长公共子序列)动规算法正确性证明
今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...
随机推荐
- linux下查看当前登陆的用户数目
在shell下输入以下语句即可获取: who | awk '{print $1}' | sort | uniq | wc -l
- Anaconda中常用的用法
Anaconda中常用的用法 conda 是开源包(packages)和虚拟环境(environment)的管理系统. packages 管理: 可以使用 conda 来安装.更新 .卸载工具包 ,并 ...
- (CLR via C#学习笔记)任务和并行操作
一 任务 可以调用ThreadPool的QueueUserWorkItem方法发起一次异步的计算限制操作.但这个技术有很多限制.最大的问题是没有内建的机制让你知道操作在什么时候完成和操作完成时的返回值 ...
- Angular2 表单验证相关
angular4响应式表单与校验http://blog.csdn.net/xiagh/article/details/78360845?locationNum=10&fps=1 How to ...
- torchnet+VGG16计算patch之间相似度
torchnet+VGG16计算patch之间相似度 torch VGG16 similarity 本来打算使用VGG实现siamese CNN的,但是没想明白怎么使用torchnet对模型进行微调. ...
- java读取PHP接口数据的实现方法(四)
PHP文件: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 3 ...
- java Web 工程servlet中@WebServlet("/HelloServlet") 是怎么工作的
编写好Servlet之后,接下来要告诉Web容器有关于这个Servlet的一些信息.在Servlet 3.0中,可以使用标注(Annotation)来告知容器哪些Servlet会提供服务以及额外信息. ...
- Java基础——概述
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- Xilinx Microblaze Bootloader
作者:Hello,Panda 一般而言,Xilinx Microblaze会被用来在系统中做一些控制类和简单接口的辅助性工作,比如运行IIC.SPI.UART之类的低速接口驱动,对FPGA逻辑功能模块 ...
- IE兼容BUG汇总及解决方案(持续更新)
本篇为总结开发过程当中遇到的各种IE兼容性的小问题,比较复杂的会单开一篇文章来讲解. 另:我手头目前只有原生IE8,原生IE9,原生IE11,以及IE11模拟的IE5,7,8,9,10.因IE6太过古 ...