又见拦截导弹
时间限制:3000 ms | 内存限制:65535 KB
难度:3
- 描述
-
大家对拦截导弹那个题目应该比较熟悉了,我再叙述一下题意:某国为了防御敌国的导弹袭击,新研制出来一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度。突然有一天,雷达捕捉到敌国的导弹来袭。由于该系统存在缺陷,所以如果想把所有的导弹都拦截下来,就要多准备几套这样的导弹拦截系统。但是由于该系统成本太高,所以为了降低成本,请你计算一下最少需要多少套拦截系统。
- 输入
- 有多组测试数据。
每组数据先输入一个整数N(N≤3000),代表有N发导弹来袭。接下来有N个数,分别代表依次飞来的导弹的导弹的高度。当N=-1时表示输入结束。 - 输出
- 每组输出数据占一行,表示最少需要多少套拦截系统。
- 样例输入
-
8 389 207 155 300 299 170 158 65 5 265 156 123 76 26
- 样例输出
-
2 1
经典的dp问题,一开始忘记n==-1停止计算,收获wa一枚。。。细心啊!!这题属于导弹拦截问题的变形,直接把导弹拦截的代码变一个地方就可以了,导弹拦截计算的是最长下降子序列,而需要的拦截系统的数目恰恰是最长上升子序列,就是把描述各个进攻导弹高度的数组从后往前看然后计算最长下降子序列。想明白这个代码就很好写了
AC代码:
#include <cstdio> #include <iostream> #include <cstring> using namespace std ; int a[3005] ; int b[3005] ; int n ; int main() { while(scanf("%d",&n)!=EOF && n!=-1) { for(int i = 0 ;i<n ;i++) scanf("%d",&a[i]) ; int max1 = 0 ; for(int i = 0 ;i<n; i++) { int max = 0 ; for(int j = 0 ;j<i ;j++) { if(b[j]>max && a[j]<a[i]) //这个地方是<号 max = b[j] ; } b[i] = max+1 ; if(b[i] > max1) max1 = b[i] ; } printf("%d ",max1) ; } return 0 ; }