【原创】【NOIP1999】拦截导弹
来源:互联网 发布:广联达软件下载教程 编辑:程序博客网 时间:2024/06/05 03:25
[NOIP1999]拦截导弹
时间限制: 1 Sec 内存限制: 64 MB提交: 666 解决: 233
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入
第1行:依次输入若干个导弹的高度H(1≤H≤30000),导弹的个数N≤5000
输出
第1行:一个整数,表示单枚炮弹能拦截多少导弹 第2行:一个整数,表示拦截所有导弹最少要配备多少套这种导弹拦截系统
样例输入
389 207 155 300 299 170 158 65
样例输出
62
提示
第2问最直观的算法是贪心,但是反例也容易找到,如:
6 5 1 7 3 2
如果第一次打6 5 3 2,显然还要打两次,而最好的方案是6 5 1/7 3 2。
这是一道很经典的题目,题里涵盖了对动归,搜索,贪心的考察。那么,就让我们好好地来分析分析这道题目吧。
这道题目有两个小问。先来看看第一个小问。
我在题目中用红色标记出了一些关键信息,透过这些信息,我们可以发现,这个炮弹是从高往低掉,看来我们要找“最长下降序列”?不不不,再看看那几个红得发黄的字,“不得高于”!
注意了,是“最长不上升序列”!是“≤”!
别被坑了!(我也被坑了!)
好啦,怎么找这条序列呢?
首先,我们要找的这串数要满足两个条件,“最长”和“不上升”。
就是说这串数每个数都≤上一个数,而且这串数里的数字最多。
那么,我们只需要把每一串都找出来再比较长短就okay了!
You say:啊?那有几千几万种情况你找得完?
Too naive!
为了保证最长,我们要让每一串数的起始位置尽量往前,终止位置尽量往后,没错吧?
所以,我们只需枚举这n个数,以第i个数为这串数的起始位置,看谁串的数多,就可以了。
下一个问题,最少(发)射几(发)炮(弹才能打完所有的导弹)?
~v~手动滑稽中~v~
提示已经告诉我们了,贪心。
提示也说了,不可以打最长不上升序列。
那怎么办呢?
别急,先来分析一下为什么“不可以打最长不上升序列”,
这是题目给的反例:6 5 1 7 3 2
最佳方案是:6 5 1 // 7 3 2
再来一组数据:4 3 4 7 6 2 1
最佳方案:4 4 2 1 // 3 // 7 6 或者 4 3 2 1 // 4 // 7 6 或者 4 4 // 7 6 2 1 // 3
来,来找规律!
我们可以发现,每一个“//”内都是不上升序列。为了让“//”更少,我们要保证每一条序列的长度都要尽量长。
这就是“不可以打最长不上升序列”的原因。我们打掉最长的,但剩下的几组的长度就不一定很长了。
所以,我们只需要再找序列的时候,让它尽可能长,就可以了。
而不是找到最长的一条,打掉;再找一条,再打掉……
讲了这么多,那就详见代码吧:
#include<cstdio>#include<algorithm>using namespace std;int n=1,a[6006],da=-1,db,yx,f[6006],much;void preparation(){while(scanf("%d",&a[n])!=EOF) n++;n--;}void step_one(){for(int i=1;i<=n;i++){int e=0;for(int j=1;j<i;j++)if(a[j]>=a[i] and e<f[j]) e=f[j];f[i]=e+1;if(da<f[i]) da=f[i],db=i;}printf("%d\n",da);}void step_two(){much=a[1],yx=0;for(int i=1;i<=n;i++)if(a[i]>=0) {much=a[i];for(int j=i+1;j<=n;j++)if(a[j]>=0 and a[j]<=much)much=a[j],a[j]=-66;yx++;}printf("%d",yx);}int main(){preparation();step_one();step_two();}
1 0
- 【原创】【NOIP1999】拦截导弹
- [NOIP1999]拦截导弹
- rqnoj[NOIP1999]拦截导弹
- rqnoj[NOIP1999]拦截导弹
- NOIP1999 拦截导弹
- NOIP1999拦截导弹
- NOIP1999拦截导弹
- 【NOIP1999】拦截导弹
- [NOIP1999]拦截导弹
- 【NOIP1999】拦截导弹
- 拦截导弹noip1999
- [NOIP1999]拦截导弹
- 【NOIP1999】拦截导弹
- 【动态规划】NOIP1999 拦截导弹
- noip1999(提高组) 导弹拦截
- noip1999导弹拦截c++语言
- Dilworth定理/NOIp1999拦截导弹
- [NOIP1999]导弹拦截NlogN做法
- QT开发之IP协议
- Android greenDAO的使用,工具类封装
- 对称矩阵的压缩存储
- 牛客:剑指offer:数字在排序数组中出现的次数 (Java)
- 解决友盟分享的报错的利器——debug模式
- 【原创】【NOIP1999】拦截导弹
- Wildfly配置PostgreSQL数据源
- 剑指offer面试题7:用两个栈实现队列(Java实现)
- CCF编译出错
- <STL>模拟实现Vector
- 欢迎使用CSDN-markdown编辑器
- 正则表达式的基本知识
- 【寒江雪】密码编码学与网络完全前言
- Remove Nth Node From End of List