一道pascal编程题目,真搞不懂为什么会错,求大神指点一下!看了很多遍都没有错误的啊。

某日,阳光镇举行一场游泳比赛,比赛规则是,每个学校只能派出5个选手参赛,谁游完M千米哪个学校的用时最少,哪个小学就获胜。(每个选手都必须至少要游一公里)现有多个学校参赛:中心小学,实验小学,龙腾小学.........你作为龙腾小学的信息学组长,游泳教师给出你这个5个最佳选手测试后,得到的每个人连续游1、2、3、……、n公里的最短时间。他准备精心安排每个队员跑的公里数,使全队完成游泳比赛用时最短。你能帮教练做一个最佳方案吗?(数据保证最佳方案唯一)
输入
m n(m<=5000,n<=1000)
下接5行,每行n个整数(表示每人连续游1-n公里的最短时间,以空格相隔)
输出
第一行:最短时间(时间<=maxlongint)
第二行:五个整数(表示安排1~5号队员各自连续游的公里数,以空格相隔)
样例输入
25 10
333 700 1200 1710 2240 2613 3245 3956 4778 5899
300 610 960 1370 1800 2712 3834 4834 5998 7682
298 612 990 1560 2109 2896 3790 4747 5996 7654
289 577 890 1381 1976 2734 3876 5678 6890 9876
312 633 995 1467 1845 2634 3636 4812 5999 8123
样例输出:
9748
6 5 5 4 5
[数据范围]
对于50%的数据,n<=500,m<=2500
对于100%的数据,n<=1000,m<=5000
我的程序是这样子的:
var f:array[0..5] of longint;
a,b:array[0..5,0..1000] of longint;
i,j,k1,k2,l,n,m,min,s:longint;
begin
readln(m,n);
for i:=1 to 5 do
for j:=1 to n do
begin
read(b[i,j]); a[i,j]:=b[i,j]-b[i,j-1];
end;
for i:=1 to 5 do f[i]:=1;
m:=m-5;
while l<m do
begin
min:=maxlongint;
for i:=1 to 5 do
if (a[i,f[i]+1]<>0)and(a[i,f[i]+1]<min) then
begin
min:=a[i,f[i]+1]; k1:=i;
end;
inc(f[k1]); inc(l);
end;
for i:=1 to 5 do inc(s,b[i,f[i]]);
writeln(s);
for i:=1 to 5 do write(f[i],' ');
end.
这个跟之前的已经修改了一些,但为什么还是会错,实在搞不懂哪里错了呢?!

你用的方法是贪心,这是错误的
例如一组数据
7 3
1 4 10
1 6 10
1 6 10
1 6 10
1 5 1

你程序输出的答案是
12
2 1 1 1 2
而正确答案是
11
1 1 1 1 3
温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-04-16
程序似乎正确。但还是可做些优化:
var    
f:array[1..5] of longint; 
a:array[1..5,1..1000] of longint; 
i,j,k1,k2,l,n,m,min,s,k:longint;
ff:text;
begin
        assign(ff,'游泳比赛.in'); reset(ff);
      readln(ff,m,n);
for i:=1 to 5 do for j:=1 to n do begin read(ff,a[i,j]); end;
      close(ff);
for i:=1 to 5 do for j:=n downto 2 do a[i,j]:=a[i,j]-a[i,j-1];
        for i:=1 to 5 do f[i]:=1;
        m:=m-5;
s:=0;
for i:=1 to 5 do s:=s+a[i,1];
        while m>0 do
        begin
                dec(m); k1:=0; min:=maxlongint;
                for i:=1 to 5 do
                        if (f[i]<n)and(a[i,(f[i]+1)]<min) then
                        begin
                                min:=a[i,(f[i]+1)]; k1:=i;
                        end; 
inc(f[k1]); s:=s+min;
        end;
        writeln(s);
        for i:=1 to 5 do write(f[i],' ');
end.
运行结果:
21835
14 40 21 24 1 

和穷举法的最优解略有差异( 21829   15    40    20    24     1)。原因就是速度的波动造成的。

追问

可是您这个还是错了啊。。。。。这个运行结果是错的啊。就是不知道怎么改。

{您看一下私信吧}

追答

这是针对你4月15日的问题的算例的结果!

追问

那假如是要全部正确呢?

追答

目前我还没想出好方法。小规模穷举可解决,大规模有超时问题 !

追问

额,无语了。

追答

既然是比赛,就要拼全力。按人的体能,游泳的速度总体是逐渐下降的,极端情况是等速。按此准备你的算例,你的方法就是对的。
所以不是什么数据罗列出来就能当算例的。

追问

那这个就没有一个很好的办法了吗??

...........

本回答被网友采纳