银河的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++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

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最为重要的