题目描述

给定一个数列,包含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. 51Nod 1509 加长棒(隔板法)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1509 思路: 直接去解可行的方法有点麻烦,所以应该用总的方法去减去不可行 ...

  2. TreeMap的应用

    public class SortedMap { //treemap按key排序,默认是升序,可自定义降序 public static void main(String[] args) { Map&l ...

  3. Binary Tree Level Order Traversal,层序遍历二叉树,每层作为list,最后返回List<list>

    问题描述: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ...

  4. java中字面量,常量和变量之间的区别(附:Integer缓存机制)

    一.引子 在各种教科书和博客中这三者经常被引用,今天复习到内存区域,想起常量池中就是存着字面量和符号引用,其实这三者并不是只在java中才有,各个语言中都有类似的定义,所以做一下总结,以示区分. 二. ...

  5. 查找一个Class到底在那一个jar文件里

    整理自己的一些笔记,发觉这个命令 ,看起来是用来找一个Class到底在那一个jar文件里的. 虽然没有再测一下,估计是好使的. 先在博客园里记下来,防止自己忘掉. findstr /S /M org. ...

  6. .net core部署到linux

    1.Install the .NET SDK 我的服务器是腾讯云的Ubuntu 16 注册Microsoft密钥和订阅源 wget -q https://packages.microsoft.com/ ...

  7. <p>1、查询端口号占用,根据端口查看进程信息</p>

    2017年6月份的时候,我就着手在公司推广git,首先我自己尝试搭建了GitLab来管理代码,并且通过以下博客记录了GitLab的搭建,以及GitLab备份,GitLab升级等事情. git学习——& ...

  8. 动态创建OATipBean

    动态创建OATipBean. 动态创建的OATipBean无法直接设置提示内容,需要添加一个静态文本. 参考User Guide示例如下. If you need to create a tip pr ...

  9. 在将对象数组转换为json字符串

    private List<WHCombineBatchFragmentBarcodeEnterEvent.Message.Data> dataList = new ArrayList< ...

  10. 由于BOM头导致的Json解析出错

    上周五改完一些BUG后,测试通过就安心在家过了个周末.结果周一回来一看,整个安卓APP所有的接口都挂掉了1.查找bug 首先想到的是客户端代码有问题,然后想起来上周五还能运行得好好的手机也是同样的错误 ...