题目
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,
但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2
思路
也可以用动态规划的思想做(最长上升子序列的某个变形)
答案其实就只是一个最长上升子序列的个数(数字的大小应该是比前一个小)
在发射了一个导弹之后有发射一个导弹之后,天空中就有两个导弹了,这两个导弹都可以进行拦截,然后在同样可以拦截的情况下,和他高度差绝对值小的导弹优先
贪心算法:临时变量,用于记录当前最小高度差,找到最小的高度差,并记录是第几个导弹,当前导弹的高度大于所有已发射导弹的高度,发射一枚新的导弹,并记录其高度值,导弹发射数量加1,如果可以拦截,则高度差最小的导弹高度下降并拦截之。
差值如果比之前的小就证明拦截不了了,按理来说差值是越来越大才能拦截
一开始N那里是50的话就超时了,好像还越界了,要把数组开大一点
代码
```cpp
#include <stdio.h>
#define N 10000//这个大小够用!空间换时间!
int compare(int *a,int n)
{
int i,j,cha,count=1,b[N],min=30000,small;
b[0]=30000;//第一个系统第一发默认高度
for(i=0;i<n;i++)
{
for(j=0;j<count;j++)//依次比较每个系统
if(b[j]>a[i])//a是进来的导弹
{
cha=b[j]-a[i];//依次比较差值
if(cha<min)//如果差值小于拦截系统的高度,说明可以拦截
{
min=cha;//更新上升子序列
small=j;//记录差值小的系统是几号
}
}
if(min==30000)//如果没经历上面那个if,min数值就不会变,所以说明了没拦截成功,因为拦不住,所以要发射导弹
{
small=count;
count++;//就这样多了一个系统
}
b[small]=a[i];//把此导弹高度存入差额最小的拦截系统,因为min不等于30000,所以b[j]=b[small]=a[i],即导弹的变化下降来拦截了
min=30000;//还能接着拦截,所以重置数据
}
return count;
}
int main()
{
int i,count,n,a[N];
while(scanf("%d",&n)!=-1)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
count=compare(a,n);
printf("%d\n",count);
}
return 0;
}