JZOJ8.16(C组)过河问题

    xiaoxiao2026-06-14  5

    题目:

    在一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸。而东岸有一条小船。 船太小了,一次只能乘坐两人。每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较长的人所用时间。 现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河。 注意,只有船在东岸(西岸)时东岸(西岸)的人才能坐上船划到对岸。

    分析:

    这题就十分类似此前的几个小盆友拿着手电筒过独木桥的题目。经过不断的推导,最优方法只能在两种方法之中诞生,一种是最快的那个人带一个最慢的也就是Time[I](因为先前快排过所以越后面就是越慢的老头),最快的那个人再把船送回来;另一种是t[1]和t[2]一起先过去,记录了t[2]的时间一次,然后T[1]回来,记录了T[1]的时间,再让两个最慢的老头过去,也就是T[I]和T[I-1],再让T[2]把船送回来。综合起来,得到状态转移方程:f[i]:=min(f[i-1]+time[1]+time[i],f[i-2]+time[1]+time[i]+time[2]*2);初始化是f[1]=a[1],f[2]=a[2];

    附上代码:

    const   maxn=100000; var   time,f:array [0..maxn] of longint;   n:longint; procedure init; var   i:longint; begin   readln(n);   for i:=1 to n do     readln(time[i]); end; procedure qsort(l,r:longint); var   i,j,k,mid:longint; begin   i:=l;   j:=r;   mid:=time[(l+r) shr 1];   repeat     while time[i]<mid do       inc(i);     while time[j]>mid do       dec(j);     if i<=j then       begin         k:=time[i];         time[i]:=time[j];         time[j]:=k;         inc(i);         dec(j);       end;   until i>j;   if l<j then     qsort(l,j);   if i<r then     qsort(i,r); end; function min(a,b:longint):longint; begin   if a<b then     exit(a);   exit(b); end; procedure main; var   i,j:longint; begin   qsort(1,n);   f[1]:=time[1];f[2]:=time[2];   for i:=3 to n do     f[i]:=min(f[i-1]+time[1]+time[i],f[i-2]+time[1]+time[i]+time[2]*2);   write(f[n]); end; begin   init;   main; end.

    转载请注明原文地址: https://ju.6miu.com/read-1310505.html
    最新回复(0)