什么是最长递增子序列(Longest Increasing Subsquence)

对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5}, {1}

其中最长的递增子序列是{2, 4, 5}

问题:对于长度为N的矢量D,如何找到它的最长递增子序列

一个简单的算法

for (i=N; i>0; --i) {. 找到所有长度为i的子序列;   //复杂度为(N!)/(i!)(N-i)!    O(exp(N))
. 判断是否其中有一个为递增子序列
}

动态规划算法

基本思想:将一个复杂问题,分解为更小的子问题

首先定义LIS[i],表示以D[i]结尾的最长子序列

对于矢量D = {, , , , , };

LIS[]:
LIS[]:
LIS[]: ,
LIS[]: ,
LIS[]: ,,
LIS[]:

给出递推公式

LIS[0] = D[0]

LIS[i] = MAX(LIS[j] | j <i, D[j] <D[i]) + "D[i]"

解释:

当我们求LIS[i]时,对于任意j<i,LIS[j]都已知

在所有已知的LIS中,找出结尾的元素值小于D[i],长度最长的一个

然后在后面加上D[i]元素,即为LIS[i]

示例C++代码

using namespace std;

void prt(vector<int>& arr, string msg = "") {
cout << msg << " ";
for (auto i: arr) {
cout << i << " ";
}
cout << endl;
} void calc_LIS(vector<int>& D) {
vector< vector<int> > L(D.size()); // The longest increasing subsequence ends with D[i] L[].push_back(D[]); for (int i=; i<D.size(); i++) {
for(int j=; j<i; j++) {
if ( (D[j] < D[i]) && ( L[i].size() < L[j].size() ) ) {
L[i] = L[j];
}
}
L[i].push_back(D[i]);
} for (auto x: L) {
prt(x);
}
} int main() {
int a[] = {, , , , , };
vector<int> arr(a, a + sizeof(a)/sizeof(a[])); prt(arr, "Data In:");
calc_LIS(arr); return ;
}

复杂度分析

时间复杂度是O(N^2)

动态规范的基本思想是以一定的空间开销,显著缩短时间开销

算法实践--最长递增子序列(Longest Increasing Subsquence)的更多相关文章

  1. 算法实践--最长公共子序列(Longest Common Subsquence)

    什么是最长公共子序列 X=ACCG Y=CCAGCA 长度为1的公共子序列: {A} {C} {G} 长度为2的公共子序列:{AC} {CC} {CG} {AG} 长度为3的公共子序列:{ACG} 长 ...

  2. 最长递增子序列(Longest increasing subsequence)

    问题定义: 给定一个长度为N的数组A,找出一个最长的单调递增子序列(不要求连续). 这道题共3种解法. 1. 动态规划 动态规划的核心是状态的定义和状态转移方程.定义lis(i),表示前i个数中以A[ ...

  3. 【转】动态规划:最长递增子序列Longest Increasing Subsequence

    转自:https://www.cnblogs.com/coffy/p/5878915.html 设f(i)表示L中以ai为末元素的最长递增子序列的长度.则有如下的递推方程: 这个递推方程的意思是,在求 ...

  4. 最长递增子序列(Longest Increase Subsequence)

    问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8 ...

  5. 300最长上升子序列 · Longest Increasing Subsequence

    [抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...

  6. [Swift]LeetCode300. 最长上升子序列 | Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  7. [Swift]LeetCode329. 矩阵中的最长递增路径 | Longest Increasing Path in a Matrix

    Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...

  8. nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)

    最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n).  具体分析参考:http://b ...

  9. 动态规划--最长上升子序列(Longest increasing subsequence)

    前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...

随机推荐

  1. 『PyTorch』第五弹_深入理解Tensor对象_下:从内存看Tensor

    Tensor存储结构如下, 如图所示,实际上很可能多个信息区对应于同一个存储区,也就是上一节我们说到的,初始化或者普通索引时经常会有这种情况. 一.几种共享内存的情况 view a = t.arang ...

  2. CSS选择器 nth-child 和 nth-of-type

    Css 3 中两个新的选择器 nth-child 和 nth-of-type 都可以选择父元素下对应的子元素,但它们到底有什么区别呢? :nth-child(n) 选择器匹配属于其父元素下的第n个子元 ...

  3. mysql 表中已经存在数据 修改字段类型 varchar(11) 改为 int(11)

    update tablename set s_role = '' alter table  tablename  modify column s_role int(11)

  4. commons-lang3工具类学习(二)

    三.BooleanUtils 布尔工具类 and(boolean... array) 逻辑与 BooleanUtils.and(true, true)         = true    Boolea ...

  5. day32-python阶段性复习六

    面向对象编程的一种方法一些皆对象面向过程和面向对象编程面向过程编程:函数式编程.c等面向对象编程:c++ ,java,python等看具体问题用哪种方法 类和对象:是面向对象中的两个重要的概念类:是对 ...

  6. oracel sql分组求和过滤条件

  7. java中一些对象(po,vo,dao,pojo)等的解释

     一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何对 ...

  8. HDU5616 天平能否称出物体重量问题 01背包变形或者折半搜索

    //hdu5616 void solve1(){dp[0]=1;for(int i=1;i<=n;i++){for(int j=INF;j>=val[i];j--){dp[j]|=(dp[ ...

  9. wire [7:0] regAddr; 理解

    首先要指出的是wire[7,0]a和wire[8,1]a这样的表达在verilog中是错误的,应该写成wire[7:0]a和wire[8:1]a wire[7:0]a表示定义了一个wire型数据,该数 ...

  10. Msfvenom学习总结

    1.    –p (- -payload-options) 添加载荷payload. 载荷这个东西比较多,这个软件就是根据对应的载荷payload生成对应平台下的后门,所以只有选对payload,再填 ...