【水】uva10037 过桥
给出n个人所需过桥的时间,每次最多两人过桥,过桥时间为最长的人的时间。求最快所有人全部过桥方案。
贪心。先从小到大排,易知
n=1 时 ans=a[1]
n=2,ans=max(a[1],a[2])
n=3,ans=a[1]+a[2]+a[3]
初始化F[1、2、3],记F[n](n>=4)为前n个人过河且1、2个人在河左岸时所用的最短时间。要弄两个人过去易得两种方案:
- 1到右岸去,带i-1回来,1再到右岸,带i回来,用时是2*a[1]+a[i-1]+a[i]
- 1到右岸去,i-1、i一起回来,2到右岸,带1回来(适用于a[i-1]、a[i]较大且相差较小时),用时a[1]+2*a[2]+a[i]
故F[n]=Min{2*a[1]+a[i-1]+a[i],a[1]+2*a[2]+a[i]}+F[n-2]
转移时记下是第几种方案。若n为奇数从3一步步向后推,若n为偶数从2开始推。
# | Problem | Verdict | Language | Run Time | Submission Date | |
11591812 | 10037 | Bridge | Accepted | PASCAL | 0.016 | 2013-04-11 13:49:55 |
program p10037; Const sol1=true; sol2=false; Var a,f:array[0..1002] of longint; g:array[0..1002] of boolean; t,n,i,o:longint; Procedure fopen; begin assign(input,'p10037.in'); assign(output,'p10037.out'); reset(input); rewrite(output); end; Procedure fclose; begin close(input); close(output); end; Function max(a,b:longint):longint;inline; begin if a>b then exit(a);exit(b); end; Procedure qsort(l,r:longint); Var i,j,x,y:longint; begin i:=l;j:=r;x:=a[l+round(0.618*(r-l))]; repeat while a[i]<x do inc(i); while a[j]>x do dec(j); if i<=j then begin y:=a[i]; a[i]:=a[j]; a[j]:=y; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; Procedure BasicPrint(P:longint;flag:boolean);inline; begin case p of 1: begin if flag then writeln(a[1]); writeln(a[1]); //writeln; end; 2: begin if flag then writeln(max(a[1],a[2])); writeln(a[1],' ',a[2]); //writeln; end; 3:begin if flag then writeln(a[1]+a[2]+a[3]); writeln(a[1],' ',a[3]); writeln(a[1]); writeln(a[1],' ',a[2]); //writeln; end; end; end; Procedure StepPrint(P:longint;kind:boolean);inline; begin if kind=sol1 then begin writeln(a[1]); writeln(a[1],' ',a[p-1]); writeln(a[1]); writeln(a[1],' ',a[p]); exit; end; writeln(a[1]); writeln(a[p-1],' ',a[p]); writeln(a[2]); writeln(a[1],' ',a[2]); end; begin readln(t); while t>0 do begin dec(t); readln; readln(n); for i:=1 to n do readln(a[i]); qsort(1,n); if n<=3 then basicprint(n,true) else begin f[1]:=a[1]; f[2]:=max(a[1],a[2]); f[3]:=a[1]+a[2]+a[3]; for i:=4 to n do if 2*a[1]+a[i-1]+a[i]<=a[1]+2*a[2]+a[i] then begin g[i]:=Sol1; f[i]:=2*a[1]+a[i-1]+a[i]+f[i-2] end else begin g[i]:=Sol2; f[i]:=a[1]+2*a[2]+a[i]+f[i-2]; end; if odd(n) then o:=3 else o:=2; writeln(f[n]); basicprint(o,false); inc(o,2); while o<=n do begin Stepprint(o,g[o]); inc(o,2); end; end; if t>0 then writeln; end;//while t end.