题目描述

给定一个数列,包含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 ]

#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元素的下标。

#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算法解析的更多相关文章

  1. 最长上升子序列LIS(51nod1134)

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...

  2. lrj 9.4.1 最长上升子序列 LIS

    p275 d(i)是以Ai为结尾的最长上升子序列的长度 <算法竞赛入门经典-训练指南>p62 问题6 提供了一种优化到 O(nlogn)的方法. 文本中用g(i)表示d值为i的最小状态编号 ...

  3. 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】

    二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...

  4. 题解 最长上升子序列 LIS

    最长上升子序列 LIS Description 给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的 ...

  5. 最长回文子序列LCS,最长递增子序列LIS及相互联系

    最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...

  6. 一个数组求其最长递增子序列(LIS)

    一个数组求其最长递增子序列(LIS) 例如数组{3, 1, 4, 2, 3, 9, 4, 6}的LIS是{1, 2, 3, 4, 6},长度为5,假设数组长度为N,求数组的LIS的长度, 需要一个额外 ...

  7. 浅谈最长上升子序列(O(n*logn)算法)

    今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...

  8. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  9. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

随机推荐

  1. [nowcoder]contest/172/C保护

    C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为首都.国家有m支军队,分别守卫一条路径的城市.具体来说,对于军队i,他守卫的城市区域可以由一对二元组(xi,yi) ...

  2. HDU 5950 Recursive sequence(矩阵快速幂)题解

    思路:一开始不会n^4的推导,原来是要找n和n-1的关系,这道题的MOD是long long 的,矩阵具体如下所示 最近自己总是很坑啊,代码都瞎吉坝写,一个long long的输入写成%d一直判我TL ...

  3. sqlite中的时间

    插入时间的sql语句 ','-61') 时间格式'2014-11-17T19:37:32' 年月日和时分秒之间多了一个字母T,保存到数据库的时候,会自动给时间加8个小时. 保存的结果为2014-11- ...

  4. mac上 sublime的配置,支持c++11且支持输入

    首先下载mac版本的 sublimetext3 下载链接: https://www.sublimetext.com/3 接着可以按照其他博客的方法来安装一些插件,便于我们的工作和学习 安装sublim ...

  5. 谷歌浏览器&360浏览器安装——有道云笔记插件

    谷歌浏览器: 有道云笔记插件:http://hk.chromefor.com/down.php?key=FulQTdJ9In3iXfdVicFW(点击即下载) 在谷歌浏览器里按快捷键:Alt+E  接 ...

  6. [转] sql server 跨数据库调用存储过程

    A库存储过程: create PROCEDURE [dbo].[spAAAForTest] ( ) =null , ) =null ) AS BEGIN select N'A' AS a , N'B' ...

  7. Gym 101246G Revolutionary Roads

    http://codeforces.com/gym/101246/problem/G 题意: 给出一个有向图,现在可以把图中的任意一条边改为无向边,问强连通分量最多可以有多少个点,在此情况下输出所有能 ...

  8. Redis复制(replication)

    介绍 Redis支持简单的主从(master-slave)复制功能,当主Redis服务器更新数据时能将数据同步到从Redis服务器 配置 在Redis中使用复制功能非常容易 在从Redis服务器的re ...

  9. (CLR via C#学习笔记)任务和并行操作

    一 任务 可以调用ThreadPool的QueueUserWorkItem方法发起一次异步的计算限制操作.但这个技术有很多限制.最大的问题是没有内建的机制让你知道操作在什么时候完成和操作完成时的返回值 ...

  10. android:点击popupwindow以外区域 popupwindow自动消失

    方法一(这种方法可以处理popupwindows dimiss的时候一些其他的操作,比如让其他控件的隐藏,消失等): 代码如下popupWindow.setFocusable(false);//foc ...