洛谷 P1020 导弹拦截

题目概述

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

    输入导弹依次飞来的高度(雷达给出的高度数据是不大于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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值