LIS(Longest Increasing Subsequence)是一类典型的动态规划类问题,简化描述如下:

给定$N(n) = \{1,2...,n\}$的一个排列$P(n)$,求$P(n)$中最长上升子列的长度。

譬如令$n = 6$, $N(6) = \{1,2,3,4,5,6\}$,$P(n) = \{1,4,2,5,3,6\}$。

容易发现$LIS(P(n)) = \{1,2,3,6\} or \{1,4,5,6\}...$。

起初我们拿到问题的思路是这样的,我们试着先分析序列的前缀,考虑P(n)中前k项的LIS,即试图分析$LIS(P(k)), k <= n$,

记$P(n) = A$,考虑由$k->k+1$的递推,若$A(k+1) > A(k)$,我们显然有$LIS(P(k+1)) = 1 + LIS(P(k))$,但若$A(k+1) < A(k)$,

则有$A(k+1) = max{LIS(P(i))} + 1, (A(i) < A(k+1), i <= k)$,那么这样做的复杂度为$O(n)$,求$LIS(P(n))$的复杂度为$O(n^2)$。

能不能更快点呢,我们的计算是否有冗余呢?我们知道答案是肯定的。

比如我们在检查到A(k)项时希望知道所有已经检查过的项对应的LIS的最大值,这样我们取其值加一即可得$LIS(P(k))$。

我们试图维护这样的一个数据结构,以线段树为例,我们构建一颗覆盖区间$[1...n]$的线段树,所有叶子结点value值初始化为$-∞$。

假设在检查$A(k)$之间线段树上储存了之前所有已访问过的项计算LIS时的信息,那么在计算$LIS(P(k))$时,我们取$[1,...A(k) - 1]$区间的最大值,

那么有区间内未访问项的值仍未$-∞$,已访问项的最大值即为所取,我们将其加一得到$LIS(P(k))$,为了维护该结构,将叶子结点A(k)对应的值更新为$LIS(P(k))$,

每次操作的复杂度为$O(logn)$,总复杂度为$O(nlogn)$。

虽然复杂度降低了,但是我们觉得使用线段树解决这个问题可能并非必要,能不能用更简单的方法实现同样复杂度的算法?

或者说,我们之前$O(n^2)$算法其使用的数据结构有何改进之处,如何重新组织信息才能使其更有利于解题?

------------------------------------------------------------

注意到我们之前关心的是项所对应位置,然后根据其位置查找其LIS并更新答案,实际上我们关心的只是满足$A(i) < A(k)$对应的最大LIS值,然而我们需要认识到

的是$A(k)$是在不断变化的,然而右边LIS的值则是便于处理的,并且具有单调可更新性。这就是问题解决的入口。

考虑固定LIS值,储存LIS值等于它的最小项,那么在检查A(k)时,只需用二分查找便可求得可以最为当前项前导项对应的LIS最大值,其后再对该序列用当前LIS更新即可。

时间复杂度为$O(nlogn)$,空间复杂度为$O(n)$。

高效的算法需要对原始数据加以更充分的利用,使之更容易呈现出实际问题的本质,使子问题更加主动地成为整个个问题解决的关键有效部分。

算法心得1:由$nlogn$复杂度的LIS算法引起的思考的更多相关文章

  1. 4. 文本相似度计算-CNN-DSSM算法

    1. 文本相似度计算-文本向量化 2. 文本相似度计算-距离的度量 3. 文本相似度计算-DSSM算法 4. 文本相似度计算-CNN-DSSM算法 1. 前言 之前介绍了DSSM算法,它主要是用了DN ...

  2. 3. 文本相似度计算-DSSM算法

    1. 文本相似度计算-文本向量化 2. 文本相似度计算-距离的度量 3. 文本相似度计算-DSSM算法 4. 文本相似度计算-CNN-DSSM算法 1. 前言 最近在学习文本相似度的计算,前面两篇文章 ...

  3. 《数据结构与算法之美》 <01>复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

    我们都知道,数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间.所以,执行效率是算法一个非常重要的考量指标. 那如何来衡量你编写的算法代码的执行效率呢?这里 ...

  4. 编程之法:面试和算法心得(寻找最小的k个数)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...

  5. 编程之法:面试和算法心得(字符串包含java实现)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...

  6. 编程之法:面试和算法心得(旋转字符串java实现)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b ...

  7. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  8. 算法与设计模式系列1之Python实现常见算法

    preface 常见的算法包括: 递归算法 二分法查找算法 冒泡算法 插入排序 快速排序 二叉树排序 下面就开始挨个挨个的说说原理,然后用Python去实现: 递归算法 一个函数(或者程序)直接或者间 ...

  9. Java常用排序算法+程序员必须掌握的8大排序算法

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...

随机推荐

  1. java Double封装类的对象保留两位小数

    double value = 22.365454; DecimalFormat df = new DecimalFormat("##.00");value = Double.par ...

  2. linux:问题

    1>.Xshell远程连接linux闲置时间过长会自动中断连接: 2>.在linux环境下乱码: 3>.在linux下面执行mv /bin/ls /root/bin之后执行ls就不能 ...

  3. eclipse不自动弹出提示

    最近公司电脑上的Eclipse没有了自动提示功能,也不是全部不提示,大多数情况下按下“alt+/”键还会产生提示,但是当我在java项目中邪main方法和syso的时候,“alt+/”则会失效,今天在 ...

  4. eclipse jsp 加载服务器tomcat

    1.window->Preferences

  5. SQLserver查看数据库端口 脚本

    exec sys.sp_readerrorlog 0, 1, 'listening'

  6. Codeforce Round #216 Div2

    e,还是写一下这次的codeforce吧...庆祝这个月的开始,看自己有能,b到什么样! cf的第二题,脑抽的交了错两次后过了pretest然后system的挂了..脑子里还有自己要挂的感觉,果然回头 ...

  7. 弦图的判定MCS算法(zoj1015)

    题意:裸的弦图的判定: 弦图定义:给出一个无向连通图,如果每个环中都存在至少一条弦(环中存在不相邻的两点直接相连)这样的图叫做弦图: 转载:http://blog.csdn.net/crux_d/ar ...

  8. How to wipe silicon to CPU 如何给CPU正确涂抹硅脂

    随 着计算机性能的提升,CPU的功耗也在不断的增大,虽然现在由于改进了工艺使得在功耗方面得到了一定的缓解,但由于近年来显卡性能的不断增强,也开始走上 了CPU功耗性能成正比的老路,功耗依然还是一个值得 ...

  9. ofbiz进击 第六节。 --OFBiz配置之[widget.properties] 配置属性的分析

    配置内容分析如下 # -- 定义上下文使用者 -- security.context =default # -- 定义密码限制长度最小值 -- password.length.min =5 # -- ...

  10. POJ 3356 AGTC(DP-最小编辑距离)

    Description Let x and y be two strings over some finite alphabet A. We would like to transform x int ...