洛谷 P1020 导弹拦截

来源:互联网 发布:单片机烧录软件 编辑:程序博客网 时间:2024/05/16 11:03

题目概述

    某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

    输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

解题思路

    第一问是典型的最长不上升子序列问题,状态转移方程f[i]=max(f[j]+1)(a[j]>a[i],1<=j<=i-1)。注意读入的方式就好。

    第二问采用贪心算法,开一个数组g,初始化最大值,g[i]表示第i个系统当前的高度。对于某一个导弹,无非是两种情况:使用目前已有的系统,或另开一个系统。如果目前的系统可以打到它,就使用能打的中高度最低的一个。若已有的系统都够不到它,就新开一个。这样能保证所有的系统“战斗力”损失最小。

    时间复杂度:O(n^2)

    空间复杂度:O(n)

源程序

var
 a,b,c:array[1..102]of longint;
 i,j,an1,an2,k,t:longint;
begin
 j:=0;
 while not eoln do
  begin
   inc(j);
   read(a[j]);
  end;
 for i:=1 to j do
  begin
   b[i]:=1;
   c[i]:=999999;
  end;
 for i:=1 to j do
  for k:=1 to i-1 do
   if (a[k]>a[i])and(b[k]+1>b[i]) then b[i]:=b[k]+1;
 an1:=0;
 for i:=1 to j do
  if b[i]>an1 then an1:=b[i];
 an2:=1;
 for i:=1 to j do
  begin
   t:=1;
   while a[i]>c[t] do inc(t);
   c[t]:=a[i];
   if t>an2 then an2:=t;
  end;
 writeln(an1);
 writeln(an2);
end.

0 0
原创粉丝点击