银河的c++课堂——[NOIP1999 普及组] 导弹拦截

2023-11-11 12:36

本文主要是介绍银河的c++课堂——[NOIP1999 普及组] 导弹拦截,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

题目描述

输入格式

输出格式

输入输出样例


题目描述

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

        输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

        一行,若干个整数,中间由空格隔开。

输出格式

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

输入输出样例

输入 :389 207 155 300 299 170 158 65

输出 :6 2

        读入就是用变量记一下数组当前长度,只要输入 a[++n]!=EOF ,就一直读下去。

        很明显,第一个问题是让求最长不升子序列,首先我们开两个 dp 数组,第一个 dp 数组求第一问,第二个求第二问,再开两个变量分别统计答案。我们先把第一项复制成 a 数组的第 1 项,无论如何至少你能打下来一个,所以len1​=1 ,接下来我们从第二个数组元素循环,只要小要小于 dp 数组的前一项就len1​+1 并且len1​=ai​ 可是我们如果发现了当前元素比 dp 数组末位元素大,说明这个高度会更有潜力,因为这个高度较大,我们可以多打中几枚,我们就找到比它小(注:在 upper_bound 里面 用 greater<typename>() )的一个元素把它替换掉。

        第二个问题我们试着来考虑一下,发现第二个 dp 数组的第一项也可以用 a 数组的第一项先管着,同样len2​=1 ,因为你至少要用一个系统。我们在从第二个元素扫的时候只要有一个高度比当前 dp 数组最后一个系统的高度大,你就直接再加一个系统,因为前一个系统拦截不到这里。如果不是这样我们就考虑用之前用过的一个拦截系统把这个导弹给拦截下来,这意味着这个高度同样可以使我们拦截掉更多的导弹,我们就找一个高度刚好大于或者等于它的 dp 数组中的一个元素给替换成当前拦截的导弹高度值。说到这里,各位不难想到这其实就是求得最长上升子序列。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 1000010
using namespace std;
typedef long long ll;
ll a[maxn],n=1,dp1[maxn],dp2[maxn],len1,len2;
inline void write(ll x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');
}
int main(){while(cin>>a[n]){n++;}n--,len1=1,len2=1;dp1[1]=a[1],dp2[1]=a[1];for(ll i=2;i<=n;i++){if(a[i]<=dp1[len1]){dp1[++len1]=a[i];}else{ll k1=upper_bound(dp1+1,dp1+len1+1,a[i],greater<ll>())-dp1;dp1[k1]=a[i]; }if(a[i]>dp2[len2]){dp2[++len2]=a[i];}else{ll k2=lower_bound(dp2+1,dp2+len2+1,a[i])-dp2;dp2[k2]=a[i];}}write(len1);puts("");write(len2);return 0;
}

这篇关于银河的c++课堂——[NOIP1999 普及组] 导弹拦截的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/390098

相关文章

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决