Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)
Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)
Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
Input
一行,若干个正整数最多100个。
Output
2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
Sample Input
389 207 155 300 299 170 158 65
Sample Output
6
2
Http
Luogu:https://www.luogu.org/problem/show?pid=1020
Source
二分,贪心,最长不下降子序列,单调队列
解决思路
第一问比较容易理解,就是求最长不上升子序列。动态规划的方法可以过,但复杂度是n^2的,这里介绍另外一种方法。
首先想清楚一点,求最长不上升子序列就是求倒序的最长不下降子序列。
首先来讲一下操作吧:我们用一个vector(下面命名为Arr)来进行操作,具体如下:
从后往前扫描导弹的高度,设当前高度为x,那么若Arr为空或Arr的最后一个数比x小,则直接把x放到Arr尾部。
否则,找到第一个大于x的数,将其用x替换。
这个方法为什么是对的呢?它是基于贪心的思想,就是要使得Arr中的数尽量小(因为要求最长嘛),如果实在不行,就把Arr的长度+1,把这个数直接放到尾部。
那么关于查找操作,因为从上面的操作可以看出,我们保证了Arr的有序性,所以我们就可以用二分查找来完成。笔者这里使用的是STL中的lower_bound函数,它返回的是第一个满足大于等于x的数的位置,而因为我们这里是求最长不下降子序列,所以我们还要用一个while来找到第一个大于x的数的位置。
那么第二问怎么求呢?
其实,第二问就是求最长上升子序列的长度(正序的)。具体方法和上面一样,只是不要取等。这里讲一下为什么。
我们根据最长上升子序列的性质并结合本题特征可以知道,最长上升子序列的中的每一个元素一定就是每一个系统最后打的那一个导弹,这可以由反证法得知。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxN=200;
const int inf=2147483647;
int n;
int Height[maxN];
vector<int> Arr;
int main()
{
    n=1;
    while (cin>>Height[n])
        n++;
    n--;
    Arr.clear();
    vector<int>::iterator Find;
    for (int i=n;i>=1;i--)//第一问,求倒序的最长不下降子序列
    {
        if ((Arr.size()==0)||(Arr[Arr.size()-1]<=Height[i]))//注意这里可以取等
            Arr.push_back(Height[i]);
        else
        {
            Find=lower_bound(Arr.begin(),Arr.end(),Height[i]);
            while (*Find==Height[i])//这里的while是求出第一个大于Height[i]的
                Find++;
            *Find=Height[i];
        }
    }
    cout<<Arr.size()<<endl;
    Arr.clear();
    for (int i=1;i<=n;i++)//第二问,求最长递增子序列
    {
        if ((Arr.size()==0)||(Arr[Arr.size()-1]<Height[i]))//注意这里不能取等
            Arr.push_back(Height[i]);
        else
        {
            Find=lower_bound(Arr.begin(),Arr.end(),Height[i]);
            *Find=Height[i];
        }
    }
    cout<<Arr.size()<<endl;
    return 0;
}
Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)的更多相关文章
- 动态规划——最长不下降子序列(LIS)
		最长不降子序列是这样一个问题: 下面介绍动态规划的做法. 令 dp[i] 表示以 A[i] 结尾的最长不下降序列长度.这样对 A[i] 来说就会有两种可能: 如果存在 A[i] 之前的元素 A[j] ... 
- 动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)
		分析: 完整 代码: // 最长不下降子序列 #include <stdio.h> #include <algorithm> using namespace std; ; in ... 
- 【动态规划】【二分】【最长不下降子序列】洛谷 P1020 导弹拦截
		最长不下降子序列的nlogn算法 见 http://www.cnblogs.com/mengxm-lincf/archive/2011/07/12/2104745.html 这题是最长不上升子序列,倒 ... 
- luogu P1020 导弹拦截 x
		首先上题目~ luogu P1020 导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都 ... 
- 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)
		传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ... 
- P1020 导弹拦截(nlogn求最长不下降子序列)
		题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ... 
- 【动态规划+高精度】mr360-定长不下降子序列
		[题目大意] 韵哲君发现自己的面前有一行数字,当她正在琢磨应该干什么的时候,这时候,陈凡老师从天而降,走到了韵哲君的身边,低下头,对她耳语了几句,然后飘然而去. 陈凡老师说了什么呢,陈凡老师对韵哲君说 ... 
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
		6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ... 
- 【题解】Luogu P2766 最长不下降子序列问题
		原题传送门 实际还是比较套路的建图 先暴力dp一下反正数据很小 第一小问的答案即珂以求出数列的最长不下降子序列的长度s 考虑第二问如何做: 将每个点拆点 从前向后连一条流量为1的边 如果以它为终点的最 ... 
随机推荐
- Maven打包jar类库
			项目目录>mvn clean compile 编译命令,会在你的项目路径下生成一个target目录,在该目录中包含一个classes文件夹,里面全是生成的class文件及字节码文件. 项目目录& ... 
- docker pull下来的镜像放哪儿了?
			本机docker版本 docker –version Docker version 1.进入docker 目录 root@Rightsec:~# cd /var/lib/docker root@Rig ... 
- WPF四则运算《《《《《策略模式
			设计思路: 因为之前没有用过WPF,听说和window窗体语法类似,就想着仿照之前的Window窗体做的,首先用三个textbox存储数据,添加一个comboBox,利用索引选择运 ... 
- Ubuntu登录界面添加root用户登录选项
			1.普通用户登录系统并打开终端 配置root密码 $sudo passwd 切换至root用户 $su root 输入密码 修改以下配置文件 $nano /usr/share/lightdm/ligh ... 
- Reaction to 构造之法 of Software Engineering From The First Chapter toThe Fifth Chapter(补充版)
			几个星期前,我阅读过一篇文章,一位老师教导自己的学生要积极地去阅读文学文献,其中,我很欣赏他的一句话:“Just think of liturature as if you're reading a ... 
- FindBugs插件的使用手册
			安装FindBugs直接查找eclipse的商店,查找spot Bugs 插件,安装即可 完成安装之后重启eclipse,右击项目文件或目录,会发现多了Findbugs的菜单: 使用Findbugs ... 
- 0506Scrum项目1.0
			1.确定选题. 应用NABCD模型,分析你们初步选定的项目,充分说明你们选题的理由. 录制为演说视频,上传到视频网站,并把链接发到团队博客上. 截止日期:2016.5.6日晚10点 团队名称:虫洞 团 ... 
- git 常用命令总结(一)
			1.初始化版本库: .进入工程根目录目录 .创建项目目录 mkdir 项目目录名称 .进入创建的项目中 cd 项目名称 pwd 显示当前目录 .项目初始化 git init //完成后会在项目目录下生 ... 
- [转帖]Nginx 的配置文件详解.
			nginx配置文件nginx.conf超详细讲解 https://www.cnblogs.com/liang-wei/p/5849771.html #nginx进程,一般设置为和cpu核数一样w ... 
- HashMap,HashTable,concurrentHashMap,LinkedHashMap 区别
			HashMap 不是线程安全的 HashTable,concurrentHashMap 是线程安全 HashTable 底层是所有方法都加有锁(synchronized) 所以操作起来效率会低 con ... 
