主题:请大家多帮忙啊?问题!
mythjoker
[专家分:400] 发布于 2005-10-27 16:35:00
我的初赛过了!但复赛很难呀!请大伙多教我一些,帮帮我,谢谢了!
问道题,给个思路,我自己做。
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够达到任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在使用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
Input
最多20个整数,分别表示导弹依次飞来的高度(雷达给出高度数据是不大于30000的正整数)
Output
两个整数M和N。表示:这套系统最多能拦截 M 枚导弹,如果要拦截所有导弹最少要配备 N 套这种导弹系统。
Sample Input
300 250 275 252 200 138 245
Sample Output
5 2
回复列表 (共6个回复)
沙发
mythjoker [专家分:400] 发布于 2005-10-30 18:04:00
没人帮忙吗?
板凳
kwxsyz [专家分:80] 发布于 2005-11-04 12:33:00
这个题的确很有难度,我的想法是这样的(不知道是否可行,楼主别笑):
由于M一定是小于20的了,我们可以开两个20个元素的数组,比如a,b.
a用来放输入的20个整数,b是后面备用.还要设置三个INTEGER变量M,T,K;K初始为1,M用来记录最多能拦截的炮弹数.
做20次的循环,在每一次循环里,查找输入的20个数中从大到小最多可以排出几个数,最多那个就是M了,但是这个不是平时我们所做的排序.具体做法如下:
第I次循环中,(1)以A[I]为开始数,令T:=A[I];
(2)然后查看A[I+1],如果A[I+1]>T,则跳过A[I+1],查看A[I+2],如果
A[I+2]>T,继续跳过,依此类推,当有某个A[J]>T时,K:=K+1;
且令 T:=A[J];
(3)继续(2)中的操作,直到查完20个数,找出一个M,这个M与之前第
I-1次循环后产生的最大M进行比较,如果大于之前那个M,则将当
所得M作为最大.
(4)查完后,重新进行(1)中的操作,但这次跳过第一个A[J].
20次循环结束,所得的M就是答案了,至于另一个N,现在还在想
3 楼
kwxsyz [专家分:80] 发布于 2005-11-04 12:40:00
不好意思,好象还是不完善的,继续再想想
4 楼
479686 [专家分:150] 发布于 2005-11-04 23:38:00
可以通过一个procedure判断读入的数组中最长有序子集的长度 这个就是最大拦截数
第二问 可以判断数组由多少个最大有序子集构成 就可以得出需要几套拦截系统
初步想法 仅供参考~
5 楼
kwxsyz [专家分:80] 发布于 2005-11-05 11:49:00
上一楼的想法完全正确,作晚我已经写出第一问的程序,这里贴出来,大家讨论讨论
program checklong;
type a=array[1..8] of longint;
var
i,j,M,N,t,TM,tem:longint;
data:a;
{temp:a;}
begin
for i:=1 to 8 do
begin
read(j);
data[i]:=j;
end;
TM:=1;
for i:=1 to 8 do
begin
readln;
M:=1;
writeln(i:4);
t:=i;
tem:=data[t];
while t>1 do
begin
if tem<data[t-1] then
begin
tem:=data[t-1];
M:=M+1;
end;
t:=t-1;
end;
t:=i;
tem:=data[t];
while t<8 do
begin
if tem>data[t+1] then
begin
tem:=data[t+1];
M:=M+1;
end;
t:=t+1;
end;
if M>TM then TM:=M;
end;
writeln('the M is:',TM:4);
end.
最后求出的M就是最大拦截数,这里只是以8个数做了测试.
6 楼
mythjoker [专家分:400] 发布于 2005-11-05 14:31:00
[em2][em2][em2]
谢谢大家了,我这几天又看了些书.这道题用的求最长不降子序列.
动态规划的原理和你们的想法大都一样!所以谢谢了.
我来回复