五:LIS

概念

最长上升子序列(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列。比如一个序列31 2 6 3 8,他的最长上升子序列是1 2 6 8或者1 2 3 8;可以不是连续的元素。而需要注意的是子串的定义是连续元素。

关于LIS的朴素算法时间复杂度达到o(n^2),在做题中并不适用,重点分析另一种时间复杂度为o(n log n)的算法。

问题描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统。

基本要求

输入

输入若干组数据,每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)

输出

对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.。

测试数据

输入

8

389 207 155 300 299 170 158 65

输出

2

算法思想

应该求最长不降子序列。这样的长度才是最少需要的套数,因为这个序列中的任何两个导弹都不能共用一个拦截系统,而且其余的导弹都能和这个最长序列中的某个导弹分为同一组。

所以此题就转变为求一个序列的最大上升子序列的长度。

实现过程

定义已知序列数组为dp[];dp[1…8]=389,207,155,300,299,170,158,65

我们定义一个序列B,然后令 i = 1 to 8
逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了

1)首先,把d[1]有序地放到B里,令B[1] = 389,就是说当只有1一个数字389的时候,长度为1的LIS的最小末尾是389。这时Len=1。

2)然后,把d[2]有序地放到B里,d[2]=207<B[1]=389,所以令B[1] = 207,就是说长度为1的LIS的最小末尾是207,d[1]=389已经没用了。这时Len=1

3)接着,d[3] = 155<B[1]=207,所以令B[1]=d[3]=155,就是说长度为1的LIS的最小末尾是155,这时候B[1] = 155,Len=1

4)再来,d[4] = 300>B[1]=155,所以B[1+1]=B[2]=300,长度为2的LIS最小末尾是300,这时候B[1..2] = 155, 300,Len = 2

5)继续,d[5] = 299,d[5]>B[1]&&d[5]<B[2]。这时令B[2]=d[5]=299,用d[5]替换掉B[2],长度为2的LIS的最小末尾是299,B[1…2]=155,299,。Len=2。

6)第6个, d[6] = 170,和上一个一样B[2]=170,长度为2的LIS最小末尾是170,B[1…2]=155,170。Len=2。

7)第7个, d[7] =158,同样B[2]=158,B[1..2]=155,158。Len=2。

8)最后一个, d[8] = 65<B[1],所以令B[1]=65,这时B[1..2]=65,158,Len=2。

于是我们知道了LIS的长度为2。

注意B中存放的并不是LIS序列,而是存储的对应长度LIS的最小末尾。有了这个末尾,我们就可以一个一个地插入数据。

在B中插入数据是有序的,而且是进行替换而不需要挪动——也就是说,我们可以使用二分查找,将每一个数字的插入时间优化到O(logN)~~~~~于是算法的时间复杂度就降低到了O(NlogN)。

代码实现

 #include<stdio.h>

 #include<iostream>

 #include<algorithm>

 using namespace std;

 int B[];

 int dp[];

 int len;

 int main()

 {

        int n;

        scanf("%d",&n);

        for(int i=;i<=n;i++)

               scanf("%d",&dp[i]);

        B[]=dp[];

        len=;

        for(int i=;i<=n;i++)

        {

               if(dp[i]>=B[len])

                      B[++len]=dp[i];

               else

                 {

                     *lower_bound(B+,B++len,dp[i])=dp[i];//调用库函数,进行二分查找第一个>=dp[i]的元素位置,返回值是指针,并替换。

                 }

        }

        printf("%d\n",len);

        return ;

 }

运行截图

个人总结

切记,B[]中存放的并不是最长上升子序列,但他含有的元素个数等于最长上升子序列的长度,在代码实现中二分查找我使用了STL库函数,返回结果是指针,还可以这样写

int *pos=lower_bound(B+1,B+1+len,dp[i]);  *pos=dp[i];效果是一样的。

LIS的更多相关文章

  1. Lis日常维护

    1.[问题]护士站打印LIs条码,出来是PDF格式的 [解决]在文件夹Client\NeusoftLis\Xml\Print.xml中把BarcodePrint Name的值改成安装的斑马打印机名(不 ...

  2. uva10635 LIS

    Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n c ...

  3. Codeforces 486E LIS of Sequence 题解

    题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两 ...

  4. 出操队形(LIS)

    题目来源:微策略2013年校园招聘面试一面试题 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往楼下跑了,然后身高矮的排在队伍的前面,身高较 ...

  5. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  6. [tem]Longest Increasing Subsequence(LIS)

    Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...

  7. 从LIS问题浅谈动态规划

    今天以LIS问题切入动态规划,现在做一些简单的总结. LIS问题: http://www.cnblogs.com/Booble/archive/2010/11/27/1889482.html

  8. [noip科普]关于LIS和一类可以用树状数组优化的DP

    预备知识 DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法,我们可以将其不严谨地先理解为递推.例如斐波那契数列的递推求法可以不严谨地认为是DP.当然DP的状态也可以 ...

  9. Hdu 3564 Another LIS 线段树+LIS

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  10. About LIS(Longest Increasing Subsequence)

    今天528给讲了基础的DP,其中第一道例题就是最长不下降子序列——LIS. 题目简述:给出N个数,求最长不下降子序列的长度. 数据范围:30% N<=1000 ; 100% N<=1000 ...

随机推荐

  1. React-native 中的触摸响应功能

    我们在做APP的时候,与桌面应用系统不同的是触摸响应. web页面对触摸响应的支持和原生的APP有着很大的差异. 基本用法 componentWillMount: function() { this. ...

  2. Winodws安装系统时,通过安装磁盘进行分区

    今天使用一个系统盘安装的时候,很奇怪,分区总是分出来一个系统磁盘,一个MBR,剩下的只能分主分区. 这样就导致我在进行windows激活时,激活工具都找不到启动磁盘的盘符(因为自动分出来的系统磁盘和M ...

  3. Young不等式的一个新证明

    设 $p>0,q>0,a>0,b>0$ 且 $1/p+1/q=1$ 有 \[ab\leq \frac{a^{p}}{p}+\frac{b^{q}}{q}\] 证明:设 \[f( ...

  4. hadoop安装与WordCount例子

    1.JDK安装 下载网址: http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u29-download-513648.html  ...

  5. 将Excel数据导入MySql

    1.将选中的数据快儿拷贝到一个TXT文本文件中(记得把后面的空格消掉..),假如存到“D:\data.txt”这个位置里. 2.根据要导入的数据快儿建立MySql数据库和表,然后进入命令提示符里使用命 ...

  6. Swift入坑--block的定义

    typealias methodCompletionBlock = (String)->Void

  7. 并发与同步 (一) ThreadLocal与Synchronized 用哪一个好

    ThreadLocal是什么? 历史 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以 ...

  8. hellogcc -100GDB技巧

    https://github.com/hellogcc/100-gdb-tips/blob/master/README.md

  9. 探索高效jQuery的奥秘

    讨论jQuery和javascript性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的jQuery和javascript代码.好的代码会带来速度的提升.快速渲染 ...

  10. plsql 连接oralce数据库,报ora 12557 tns 协议适配器不可加载错误

    使用plsql 连接oracle 数据库报ora 12557 错误: 解决方案: 1:首先确保服务中的service以及监听器都开启 2:F:\app\Administrator\product\11 ...