问题分析:
,每条船只能坐两人。
桥,那过桥的时间就是那个人的过桥时间;
桥,那过桥的时间就是慢的那个人的过桥时间;
桥,开始时间最短的两个人过桥,然后时间最短的那个人回去接时间最长的那个人,若三人过桥时间为a、b和c则过河时间是a+b+c;
桥时,就由时间最短的两个人送时间最长的两个人(反正这两人都要过桥,就先过)过桥;送两人过桥后,人数就减少两人;假设四人过河时间分别是a、b、c和d,并且a<=b<=c<=d,这时又分为两种情况过河:
桥情况是ac、a、ad和a,先把c和d先送过;
,先把c和d先送过;
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=1005; int a[maxn]; int main() { int t; scanf("%d",&t); for(int i=1;i<=t;i++){ if(i!=1){ printf("\n"); } int n; scanf("%d",&n); for(int j=0;j<n;j++){ scanf("%d",&a[j]); } sort(a,a+n); int m=n,ans=0; while(m>=4){ ans+=min(a[0]*2+a[m-1]+a[m-2],a[0]+a[1]*2+a[m-1]); m-=2; } if(m==3){ ans+=a[0]+a[1]+a[2]; }else if(m==2){ ans+=a[1]; }else if(m==1){ ans+=a[0]; } printf("%d\n",ans); while(n >= 4) { if(a[0] * 2 + a[n - 1] + a[n - 2] < a[0] + a[1] * 2 + a[n - 1]){ printf("%d %d\n%d\n%d %d\n%d\n", a[0], a[n-1], a[0], a[0], a[n-2], a[0]); }else{ printf("%d %d\n%d\n%d %d\n%d\n", a[0], a[1], a[0], a[n-2], a[n-1], a[1]); } n -= 2; } if(n == 3){ printf("%d %d\n%d\n%d %d\n", a[0], a[1], a[0], a[0], a[2]); }else if(n == 2){ printf("%d %d\n", a[0], a[1]); }else if(n == 1){ printf("%d\n", a[0]); } } return 0; }