拦截导弹
2016-06-24 16:03
176 查看
问题描述 Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。输入描述 Input Description
第一行为一个整数 N,表示飞来的导弹个数, N≤100000第二行为 N 个整数,依次表示导弹飞来的高度,高度数据为不大于 30000 的正整数。
输出描述 Output Description
第一行,输出计算这套系统最多能拦截多少导弹第二行,输出要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入样例 Sample Input
8389 207 155 300 299 170 158 65
输出样例 Sample Output
62
分析
第一问是求最长不增子序列。第二问是求最长递增子序列。可以这么想,设最长递增子序列长度为 s,因为拦截 a1 需要使用一套装置, a2>ai ,所以拦截 a2 不能用拦截 a1 的装置,a3>a2>a1 ,所以拦截 a3 不能用拦截 a2,a1 的装置…所以最少要用 s 套装置,可以利用差不多的思路证明最多要用 s 套装置
代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef bool(*cmper)(int,int); int a[100100]; int f[100100]; int n; void work(cmper); bool lower(int,int); bool Super(int,int); int binary(int,int,int,cmper); int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); work(Super); work(lower); return 0; } void work(cmper cmp1){ f[f[0]=1] = a[1]; for(int i=2;i<=n;++i){ if(cmp1(f[f[0]],a[i])) f[++f[0]] = a[i]; else if(!cmp1(f[1],a[i])) f[1] = a[i]; else f[binary(1,f[0],a[i],cmp1)] = a[i]; } printf("%d\n",f[0]); } bool lower(int a,int b){ return a<b; } bool Super(int a,int b){ return a>=b; } int binary(int L,int R,int number,cmper cmp){ int M; while(L+1 < R){ M = (L+R)>>1; if(f[M] == number){ while(f[M]==number) ++M; return M; } else if(cmp(f[M],number)) L = M; else R = M; } return R; }
相关文章推荐
- 从零开发一款APP 二、Java Web后端注册接口的实现
- android videoview 播放有声音没有画面
- SQL 处理序列化的方法
- Android中的广播机制(一)----- 接收广播
- 嵌入式学习-uboot-lesson4.2-设置SVC模式
- AFNetworking 的使用
- HorizontalListView 的selection方法
- 缓冲区溢出攻击
- C++Builder建造者模式详解--设计模式(4)
- 依赖注入 控制反转(3)
- XMG 活动指示器的制作
- Android项目重构之路:实现篇
- MongoDB学习记录—索引
- 深入理解SELinux SEAndroid(第二部分)
- 线性表之顺序表
- CJV_I——helloworld中的字符串数组与简易for循环
- QPointer很大程度上避免了野指针(使用if语句判断即可,类似于dynamic_cast),而且使用非常方便 good
- linux 环境 iftop流量监控工具安装配置
- 期末考试-拯救公主(算法基础 第10周)
- 异常处理