#include <iostream>
#include <cstring>
#include <algorithm>
#include <functional>
using namespace std;
int n = 1, a[100005], nup[10005], up[10005], len = 1, cnt = 1;
int main()
{
while((scanf("%d",&a[n])!=EOF))n++;
nup[1] = up[1] = a[1];
for (int i = 2; i < n; i ++ ){
if(nup[len] >= a[i]){
nup[++len]=a[i];
}else {
nup[upper_bound(nup+1,nup + len+ 1,a[i],greater<int>())-nup] = a[i];
}
if(up[cnt] < a[i]){
up[++cnt] = a[i];
}else{
up[lower_bound(up+1,up+cnt+1,a[i])-up]=a[i];
}
}
printf("%d\n%d\n",len,cnt);
return 0;
}
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
一行,为导弹依次飞来的高度
输出格式
两行,分别是最多能拦截的导弹数与要拦截所有导弹最少要配备的系统数
样例输入
389 207 155 300 299 170 158 65
样例输出
6
2
-
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
-
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。