题目概述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于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.