给出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;Constsol1=true;sol2=false;Vara,f:array[0..1002] of longint;g:array[0..1002] of boolean;t,n,i,o:longint;Procedure fopen;beginassign(input,'p10037.in');assign(output,'p10037.out');reset(input);rewrite(output);
end;Procedure fclose;beginclose(input);close(output);
end;Function max(a,b:longint):longint;inline;beginif a>b then exit(a);exit(b);
end;Procedure qsort(l,r:longint);
Vari,j,x,y:longint;begini:=l;j:=r;x:=a[l+round(0.618*(r-l))];repeatwhile a[i]<x do inc(i);while a[j]>x do dec(j);if i<=j then beginy:=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;begincase p of 1:beginif flag then writeln(a[1]);writeln(a[1]);//writeln;end;2:beginif flag then writeln(max(a[1],a[2]));writeln(a[1],' ',a[2]);//writeln;end;3:beginif 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;beginif kind=sol1 thenbeginwriteln(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;beginreadln(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) elsebeginf[1]:=a[1];f[2]:=max(a[1],a[2]);f[3]:=a[1]+a[2]+a[3];for i:=4 to n doif 2*a[1]+a[i-1]+a[i]<=a[1]+2*a[2]+a[i] thenbeging[i]:=Sol1;f[i]:=2*a[1]+a[i-1]+a[i]+f[i-2]end elsebeging[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 dobeginStepprint(o,g[o]);inc(o,2);end;end;if t>0 then writeln;end;//while tend.