主要内容 #
- 问题描述
- 算法思路
- 参考程序
1. 问题描述 #
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段。所以一套系统有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。
输入格式
n颗依次飞来的高度(1≤n≤1000)。
输出格式
要拦截所有导弹最小配备的系统数k。
输入样例
389 207 155 300 299 170 158 65
输出样例
2
2. 算法思路 #
假设k为当前配备的系统数目。如果导弹i的高度高于所有系统的最低高度,则断定导弹i不能被这些系统所拦截,应该增设一套系统拦截导弹;若导弹i低于某些系统的最低拦截高度,那么导弹i均可被这些系统所拦截。究竟选择哪个系统拦截可使得配备的系统数目最少,需要采用贪心策略,选择其中最低拦截高度最小的一套系统,即导弹i的与系统最低高度最接近的那一套系统。
以此类推,直至分析了n枚导弹的高度为止。此时k即为应配备的最少的系统数。
我们设定一个数组b来保存每套系统当前的最低高度,如b[1]表示的就是第一套系统的最低高度。对于每一个来袭的导弹,我们找到一个最符合条件的(贪心)即可。
那么如何找到呢?
如果a[i]< b[j] (j表示当前判断的是第几套),则这个导弹可以被此套系统拦截,此时又分两种情况:
当前来袭还没分配,分配给这一套系统,p=j;
已经分配了给某系统,判断哪个更小,如1系统500,2系统400,此时来袭导弹高度390,那么我们肯定要分配给400那套系统去拦截。
3. 参考代码 #
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int a[1001];
int b[1001];
int k,n,p;
cin>>n;
for(int i=1;i<=n;i++){//输入
cin>>a[i];
}
b[1]=a[1];//初始化,第一个导弹放第一组
k=1;//初始化,一套导弹系统
for(int i=2;i<=n;i++){
p=0;
for(int j=1;j<=k;j++){//看能不能使用已有的导弹系统
if(b[j]>a[i]){//这套系统大于a[i]的a高度
if(p==0) p=j;//p还没有指定
else if(b[j]<b[p]) p=j;
}
}
if(p==0){//没找到能用的
k++;
b[k]=a[i];
}else{
b[k]=a[i];
}
}
cout<<k<<endl;
return 0;
}