8.8 两人过桥bridge 2529

来源:互联网 发布:电脑监控软件破解 编辑:程序博客网 时间:2024/04/30 20:43

  • 题目
  • 题解
  • 代码

题目

有n个人希望在晚上通过一座桥。在任何时刻,最多只能有两个人在桥上,并且必须要带着手电筒才能通过桥。现在的麻烦是只有一个手电筒,所以必须安排某种顺序,使得手电筒可以被带回去让更多的人过桥(手电筒必须由人带回,不可以从对岸扔过去)。 每个人都有不同的过桥时间,两个人一起过桥所用的时间等于其中较慢的一个。你的任务是要找出能在最短时间内使所有人都过桥的方案。

40%的数据满足:n<=100;
100%的数据满足:n<=1000

  样例读入       样例输出     4            17     1      2      5      10

可以先让1和2过桥,然后1回来,让5和10过桥,然后2再回来带1一起过桥,时间为:2+1+10+2+2=17。

题解

贪心,先排序
有两种策略,每次取效率最高的:
1.让最快的人来回带
2.先让最快和次快的人过去,然后最快回来,最慢和次慢过去,次快单独回来,带最快过去

从小到大做和从大到小做都可以,从小到大要保持手电筒、最快和次快在右边,从大到小则保持手电筒、最快和次快在左边
时间复杂度O(n)

          |     |   左边   |      |   右边 (起点)  |     |  (终点)          |     |

代码

从大到小

var  n,i,ans:longint;  a:array[1..1000]of longint;procedure qsort(l,r:longint);var  i,j,key,t:longint;begin  if l>=r then exit;  i:=l;j:=r;  key:=a[(l+r) div 2];  repeat    while a[i]<key do inc(i);    while a[j]>key do dec(j);    if i<=j then      begin        t:=a[i];a[i]:=a[j];a[j]:=t;        inc(i);dec(j);      end;  until i>j;  qsort(i,r);  qsort(l,j);end;function min(a,b:longint):longint;begin  if a<b then exit(a) else exit(b);end;begin  readln(n);  for i:=1 to n do    readln(a[i]);  qsort(1,n);  while n>3 do    begin              ans:=ans+min(a[1]*2+a[n]+a[n-1],a[n]+a[2]*2+a[1]);      n:=n-2;    end;  if n=3 then ans:=ans+a[1]+a[2]+a[3]         else ans:=ans+a[n];  writeln(ans);end.

从小到大

var  n,i:longint;  a,f:array[1..1000]of longint;procedure qsort(l,r:longint);var  i,j,key,t:longint;begin  if l>=r then exit;  i:=l;j:=r;  key:=a[(l+r) div 2];  repeat    while a[i]<key do inc(i);    while a[j]>key do dec(j);    if i<=j then      begin        t:=a[i];a[i]:=a[j];a[j]:=t;        inc(i);dec(j);      end;  until i>j;  qsort(i,r);  qsort(l,j);end;function min(a,b:longint):longint;begin  if a<b then exit(a) else exit(b);end;begin  readln(n);  for i:=1 to n do    readln(a[i]);  qsort(1,n);  f[1]:=a[1];f[2]:=a[2];  for i:=3 to n do    f[i]:=min(f[i-1]+a[i]+a[1],f[i-2]+a[i]+a[1]+a[2]*2);  writeln(f[n]);end.
原创粉丝点击