LIS
五: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的更多相关文章
- Lis日常维护
1.[问题]护士站打印LIs条码,出来是PDF格式的 [解决]在文件夹Client\NeusoftLis\Xml\Print.xml中把BarcodePrint Name的值改成安装的斑马打印机名(不 ...
- uva10635 LIS
Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n c ...
- Codeforces 486E LIS of Sequence 题解
题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两 ...
- 出操队形(LIS)
题目来源:微策略2013年校园招聘面试一面试题 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往楼下跑了,然后身高矮的排在队伍的前面,身高较 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- [tem]Longest Increasing Subsequence(LIS)
Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...
- 从LIS问题浅谈动态规划
今天以LIS问题切入动态规划,现在做一些简单的总结. LIS问题: http://www.cnblogs.com/Booble/archive/2010/11/27/1889482.html
- [noip科普]关于LIS和一类可以用树状数组优化的DP
预备知识 DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法,我们可以将其不严谨地先理解为递推.例如斐波那契数列的递推求法可以不严谨地认为是DP.当然DP的状态也可以 ...
- Hdu 3564 Another LIS 线段树+LIS
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- About LIS(Longest Increasing Subsequence)
今天528给讲了基础的DP,其中第一道例题就是最长不下降子序列——LIS. 题目简述:给出N个数,求最长不下降子序列的长度. 数据范围:30% N<=1000 ; 100% N<=1000 ...
随机推荐
- ECSHOP模板标签
模板制作修改经常用到ecshop模板标签: 页面关键字 {$keywords }页面标题 {$page_title}产品分类父分类列表 {foreach from=$categories item=c ...
- Android Studio 编译不通过,报错“找不到org.apache.http
如果你使用的 target sdk是23请在build.gradle加入 android{ useLibrary ‘org.apache.http.legacy‘ }
- C++ 构造过程和析构过程
1.C++构造和析构的过程,类似于穿衣脱衣的过程.穿衣是:先穿内衣,再穿外套.脱衣是:先脱外套,再脱内衣.C++构造过程:首先调用父类构造方法,再调用子类构造方法.C++析构过程:首先调用子类析构方法 ...
- Git链接到自己的Github(2)进阶使用
接着上一篇的,从github clone下代码. 1.先查看当前开发分支 $ cat .git/HEAD ref: refs/heads/master 这里的master是默认分支. 2.查看当前状态 ...
- java_spring_bean的作用域_实例是否为单实例
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Mysql在windows下的免安装配置步骤和重新安装的步骤
windows下mysql免安装配置 1. 下载mysql免安装压缩包 下载mysql-5.6.22-winx64.zip 解压到本地D:\mysql-5.6.22-winx64 2. 修改配置文件 ...
- View绘制详解(二),从setContentView谈起
掐指一算,本来今天该介绍View的测量了,可是要说View的测量,那就要从setContentView谈起了,setContentView本身涉及到的东西也是挺多的,所以今天我们就先来看看这个setC ...
- swift的特点
2个不需要: 1.不需要编写main函数:从上往下按顺序执行代码,所以最前面的代码会自动当做程序的入口 2.不需要在每一条语句后面加分号(也可以加):若是有多条语句在同一行就一定要加分号 ...
- Java双向链表实现
public class DoublyLinkList { private class Data{ private Object obj; private Data left = null; priv ...
- javascript的函数传参(没有引用传递只有值传递)
var v1 = [] var v2 = {}; var v3 = {}; function foo(v1, v2, v3){ v1 = [1]; v2 = [2]; v3 = {a ...