题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

11行,若干个整数(个数\le 100000≤100000)

输出格式

22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出样例

输入 #1复制

389 207 155 300 299 170 158 65
输出 #1复制

6
2

说明/提示

为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分


看了几篇博客,讲的都是最长上升子序列的nlogn 解法:只是简单的讲了是  贪心+DP

贪心 :大部分是这样证明的:

当你从一串数中构造一个最长子序列,在选择数时 要尽量选择最大的数字作为下一个数字,因为大的数字为后续选择提供了更多选择,从而使序列变得更长;

当你这次选的数字比正在构造的最后一个数字大时,找到比你这次选的数字小于等于的地方,用这个数字替换原先存在的数字,而且,在这个替换的数字后的数字不要删掉。

形如下面这个样例:

这个样例展示的是《《《最长不上升子序列》》》

一组样例:
//90 103 99 83 102 70 86 70 99 71
//结果是:5

在构造的序列变化是:

90

103

103  99

103  99  83

103 102 83

103 102 83 70

103 102 86 70

103 102 86 70 70

103 102 99 70 70

103 102 99 71 70 //显然最后得到的不一定是真实应该得到的子序列;

103  99  83 70 70//真实应该得到的子序列

明显可以看出:真实的子序列中的数字都是曾经在此位置的数字。

将这个位置替换,其实只是在原先位置更换了一个新的用于比较的标签,因为这个新的标签更大,为后边提供了更长的可能。

此题AC代码:lower_bound(begin(),end(),x,greater<int>());  通过greater<int>()改变比较方向。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a,b,c; int main ()
{
int num,n=0;
while(cin>>num)
{
n++;
a.push_back(num);
}
n--;
for(int i=0;i<=n;i++)
{
int it=upper_bound(b.begin(),b.end(),a[i],greater<int>())-b.begin();
//cout<<it<<endl;
if(it==b.size())
b.push_back(a[i]);
else
{
b[it]=a[i];
}
int itn=lower_bound(c.begin(),c.end(),a[i])-c.begin();
if(itn==c.size())
c.push_back(a[i]);
else
c[itn]=a[i];
}
//for(auto itm:b)
// cout<<itm<<endl;
cout<<b.size()<<endl;
cout<<c.size();
return 0;
}

一个变式题目:

N位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形。

合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K1,2,…,K,他们的身高分别为T_1,T_2,…,T_KT1​,T2​,…,TK​, 则他们的身高满足T_1<...<T_i>T_{i+1}>…>T_K(1 \le i \le K)T1​<...<Ti​>Ti+1​>…>TK​(1≤i≤K)。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入格式

共二行。

第一行是一个整数N(2 \le N \le 100)N(2≤N≤100),表示同学的总数。

第二行有nn个整数,用空格分隔,第ii个整数T_i(130 \le T_i \le 230)Ti​(130≤Ti​≤230)是第ii位同学的身高(厘米)。

输出格式

一个整数,最少需要几位同学出列。

输入输出样例

输入 #1复制

8
186 186 150 200 160 130 197 220
输出 #1复制

4

数据范围非常小,可以枚举任何一个值,左边取最长上升子序列,右边取最长下降子序列

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int a[105];
int n;
int lis_1(int m)
{
vector<int>b;
for(int i=1;i<=m;i++)
{
int it=lower_bound(b.begin(),b.end(),a[i])-b.begin();
if(it==b.size())
b.push_back(a[i]);
else
b[it]=a[i];
}
return b.size();
}
int lis_2(int m)
{
vector<int>c;
for(int i=m;i<=n;i++)
{
int it=lower_bound(c.begin(),c.end(),a[i],greater<int>())-c.begin();
if(it==c.size())
c.push_back(a[i]);
else
c[it]=a[i];
}
return c.size();
} int main ()
{ cin>>n;
int ans=n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
ans=min(ans,n+1 - lis_1(i) - lis_2(i));
}
cout<<ans<<endl; return 0;
}

LIS(nlogn)算法描述//线性DP经典类型的更多相关文章

  1. lis nlogn算法

    当前所在位的最长上升子序列只和前面一个字符有关 #include <iostream> #include <algorithm> using namespace std; ]; ...

  2. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  3. nyoj44 子串和 线性DP

    线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...

  4. 线性DP总结(LIS,LCS,LCIS,最长子段和)

    做了一段时间的线性dp的题目是时候做一个总结 线性动态规划无非就是在一个数组上搞嘛, 首先看一个最简单的问题: 一,最长字段和 下面为状态转移方程 for(int i=2;i<=n;i++) { ...

  5. 最长上升子序列(LIS)长度的O(nlogn)算法

    最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...

  6. 1. 线性DP 300. 最长上升子序列 (LIS)

    最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...

  7. 线性DP LIS浅谈

    LIS问题 什么是LIS? 百度百科 最长上升子序列(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列. 怎么求LIS? O( ...

  8. AT2827 最长上升子序列LIS(nlogn的DP优化)

      题意翻译 给定一长度为n的数列,请在不改变原数列顺序的前提下,从中随机的取出一定数量的整数,并使这些整数构成单调上升序列. 输出这类单调上升序列的最大长度. 数据范围:1<=n<=10 ...

  9. 线性DP详解

    顾名思义,线性DP就是在一条线上进行DP,这里举一些典型的例子. LIS问题(最长上升子序列问题) 题目 给定一个长度为N的序列A,求最长的数值单调递增的子序列的长度. 上升子序列B可表示为B={Ak ...

随机推荐

  1. PHP 导入Excel数据 到数据库

    /** * 导入excel * @throws \PHPExcel_Exception * @throws \PHPExcel_Reader_Exception */ public function ...

  2. PHP 自定义 alert 跳转方法

    /** * 跳转方法 * @param $msg * @param null $path * @param null $parent */ public function alert($msg,$pa ...

  3. 通用寄存器_MOV_ADD_SUB_AND_OR_NOT

    通用寄存器 MOV指令 注意:目标操作数与操作数宽度必须一样 MOV 目标操作数,源操作数 作用:拷贝源操作数到目标操作数 1.源操作数可以是立即数.通用寄存器.段寄存器.或者内存单元. 2.目标操作 ...

  4. session、cookie、token的区别

    从安全性优先级来说: 1.优先级 Cookie<session<token 2. 安全性 Cookie: ①cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺 ...

  5. ctfhub技能树—信息泄露—目录遍历

    打开靶机 查看页面 点击后发现几个目录 于是开始查找 在2/1目录下发现flag.txt 成功拿到flag 练习一下最近学习的requests库 附上源码 #! /usr/bin/env python ...

  6. 什么是xss攻击

    概述: XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的,形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列 表,然后向联 ...

  7. linux搭建简单samba服务器

    1.安装需要的软体 yum install -y samba samba-client samba-common 2.创建samba需要的本地用户,创建samba服务使用的目录 Linux系统文件的读 ...

  8. [noip模拟]分组行动

    题目描述 最近,木木中学要举行一年一度的辩论赛了,我们活泼开朗乐观向上不寂寞不生病不挂科天天回家吃饭的新时代好少年--飞飞,自然是热情参与咯!辩论嘛,就有正方和反方两个组,这是一个传统项目,所以,包括 ...

  9. 上海某小公司面试题:synchronized锁原理

    synchronized锁是Java面试的过程中比较常考的知识点了,从偏向锁->轻量级锁->重量级锁都可以聊 CAS在这篇没有讲述,因为在上一篇已经写了,有兴趣的同学可以翻翻开 目前已经连 ...

  10. 笔记 | pandas之时间序列学习随笔1

    1. 时间序列自动生成 ts = pd.Series(np.arange(1, 901), index=pd.date_range('2010-1-1', periods=900)) 最终生成了从20 ...