问题描述:某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹?
输入格式:
输入只有一行,为若干个正整数(用空格隔开),依次为导弹的高度。
输出格式:
一行,为最多能拦截的导弹数。
输入样例:389 207 155 300 299 170 158 65
输出样例:6
/**************************************************************/
问题分析:
- 其实这道题是经典DP(最大单调递增子序列)的变形,建议查阅资料先掌握求最大单调子序列的算法思想再解决此题比较明朗,而这题变形在于求得是单调递减而已。
- 题目中并未直接给出输入规模大小,编程前需要注意
- 这里求最多能拦截数,所以这里有个坑,就是应该求非单增序列长度,相等的数字也算序列之一
#include<stdio.h>
#include<stdlib.h>
#include<bits/stdc++.h>
#define N 1002
using namespace std;
int main()
{
int a[N];
int dp[N];
int i,j,n,max=0;
char ch=' ';
i=0;
while(1){//读入数据,此读入数据方法在于拓宽思路,并非最简,也可直接利用scanf返回值作循环条件,这样代码更简单
if(ch=='\n'){
break;
}
scanf("%d",&a[i]);
dp[i]=1;
ch=getchar();//读入最后一个换行符
i++;
}
n=i;//读入数据个数
for(i=0;i<n;i++){
for(j=0;j<i;j++){
if(a[j]>=a[i]&&(dp[j]+1)>dp[i]) dp[i]=dp[j]+1;
//特别注意a[j]>=a[i],若无=则AC不了
}
}
for(i=0;i<n;i++){
if(dp[i]>max) max=dp[i];
}
printf("%d",max);
return 0;
}
程序运行结果: