回 帖 发 新 帖 刷新版面

主题:[讨论]防御导弹问题怎么做(ACM的题)

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

Input
最多20个整数,分别表示导弹依次飞来的高度(雷达给出高度数据是不大于30000的正整数) 

Output
两个整数M和N。表示:这套系统最多能拦截 M 枚导弹,如果要拦截所有导弹最少要配备 N 套这种导弹系统。 

Sample Input
300 250 275 252 200 138 245

Sample Output
5 2

回复列表 (共8个回复)

沙发

我最近也在研究这个问题。
第一个问就是最长下降序列。
关键是第二问,如果每次都求最靠前的最长下降序列再剔除,有些数据是过不了的,比如
12 7 11 6 10 5 9
这样得出的答案是12 11 10 5、7 6、9(3套系统)
正确答案12 11 10 9、7 6 5(2套系统)
正确答案在选择第一套系统时就没有选择最靠前的拦截。

板凳

用穷举做到是可以做出正确答案,但是效率太题,数一多就挂

3 楼

这题谁还用穷举?肯定是动归!

4 楼

动态规划不一定能得到最优解,还不如求出个正确答案呢

5 楼

正解是DP+边界扫描

6 楼


应该是贪心

7 楼

动态规划的一个比较典型的题目。。

8 楼

第一个问题很简单
第二问(网上有更详细的解析):
min[]表示的是已有系统的拦截导弹最低高度,进来新的新的导弹后导弹在已有系统中筛选如果MIN[J]<A[I]则更新系统J的最低高度,另外已知MIN[]为递增,所以
如果J可以,则J+1--K都可以。我们用贪心策略用J系统即可。
var
i,j,k,n:integer;
a,b:array[1..1000] of longint;
f:text;
  function max:longint;
  var
  i,j,k:integer;
  m:longint;
  begin
    m:=1;
    for i:=n-1 downto 1 do
      begin
        k:=1;
        for j:=i+1 to n do
          if (b[j]+1>k)and(a[i]>a[j]) then
          begin
          k:=b[j]+1;
          if m<k then m:=k;
          end;
        b[i]:=k;
      end;
    max:=m;
  end;
  function sys:integer;
  var
    i,j,k,m:integer;
    min:array[1..100] of integer;
  begin
  min[1]:=a[1];k:=1;m:=a[1];
  for i:=2 to n do
    begin
      j:=1;
      if a[i]<min[1] then min[1]:=a[i]
      else
        begin
        while (a[i]>min[j])and(j<=k) do j:=j+1;
        min[j]:=a[i];
        if j>k then k:=j;
        end;
    end;
  sys:=k;
  end;
begin
readln(n);
for i:=1 to n do read(a[i]);
b[n]:=1;
writeln(max);
writeln(sys);
end.

我来回复

您尚未登录,请登录后再回复。点此登录或注册