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 ...
随机推荐
- 【STL学习】智能指针之weak_ptr
简介 weak_ptr是shared_ptr的观察者,它不会干扰shared_ptr所共享对象的所有权,当一个weak_ptr所观察的shared_ptr要释放它的资源时,它会把相关的weak_ptr ...
- 设置 ubuntu ftp
apt-get install后就是启动不了,ftp localhost connection refued 1. 关闭ubuntu防火墙 : ufw disable 2. 还是不行,报 500 m ...
- webservice 地址
快递查询WEB服务 http://webservice.36wu.com/ExpressService.asmx 支持上百家快递/物流查询,准确高效,所有数据均来自快递服务商.此数据返回类型进行了封装 ...
- U盘安装SLES的方法
安装准备: 一个4G 或 大于4G的U盘 也同样适合移动硬盘, SLES-11-DVD-i586-GM-DVD1.iso 文件1) 将U盘格式化成FAT32格式; 2) 下载 syslinux工具 h ...
- cocos2d-x 将cocosbuilder输出文件映射成对象的原理
转自:http://www.cnblogs.com/fox7nights/archive/2013/02/21/2920640.html 一.调用代码 CCNode* GameOverScene::l ...
- Foxmail
我们在“POP3/SMTP服务”前面打钩,这样我们的QQ邮箱设置已经完成了,我们就可以在foxmail客户端上QQ邮箱了 QQ邮箱的POP3与SMTP服务器是什么? QQ邮箱 POP3 和 SMTP ...
- 安卓Android控件ListView获取item中EditText值
可以明确,现在没有直接方法可以获得ListView中每一行EditText的值. 解决方案:重写BaseAdapter,然后自行获取ListView中每行输入的EditText值. 大概算法:重写Ba ...
- ThinkPHP3.1快速入门(12)自动验证
自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 验证规则 数据验证可以进行数据类型.业务规则.安全判断等方面的验证操作.数据验证有两 ...
- [置顶] ORACLE分析函数(1)
分析函数式ORACLE提供的用来进行数据统计的强有力工具,与我们常用的聚合函数具有一些相似性,但又完全不同.聚合函数,首先会将数据进行分组,然后对每一组数据进行运算,如求和sum,求平均AVG等,对于 ...
- 去掉html标签和空格等
<?php$str = '<span style="color:#f00;">good; world</span>';echo $str.'<b ...