#include <iostream> #include <algorithm> using namespace std; /* 贪婪法: 1)当人数<3时:直接过 2)当人数=3时:假设为a,b,c.(升序) 如果用最小的来送:c+a+b=c+b+a 如果大的一起过:c+b+b=c+2b. 所以这个时候用小的来送. 3)当人数=4时,a,b,c,d(升序) 如果用最小的来送:d+a+c+a+b=d+c+b+2a 如果先让最小的两个过河,再让其中一个回来, 让最大的两个过河,再让前一步过去留下的那个回来, 再让最小的2个过河 也就是说小的两个过去2次,再单独回来一次. 2b+b+a+d=d+3b+a 当d+c+b+2a<=d+3b+a时,也就是c-2b+a<=0时,第一种方法过. 否则用另外一种办法 4)当人数>4时,a,b,..,c,d(升序) 过去,回来,过去,回来(船要回来),让最大的2个过去. 很笨的时间是d+c+c+a=d+2c+a(所有时间都写出来后会发现时最慢的) 如果让最小的来送:d+a+c+a=d+c+2a 否则:b+b+a+d=d+2b+a 如果d+c+2a<=d+2b+a,也就是c-2b+a<=0时,第一种方法过 */ int main() { //freopen("in.txt", "r", stdin); int p[1005],t,n; cin>>t; while(t--) { cin>>n; int i = 0; while(i < n) cin>>p[i++]; sort(p, p + n);//左闭右开 int sum = 0; while(n) { if(n == 1) { sum += p[0]; n = 0; } else if(n == 2) { sum += p[1]; n = 0; } else if(n == 3) { sum += (p[0] + p[1] + p[2]); n = 0; } else if(n == 4) { if(p[2] - 2 * p[1] + p[0] <= 0) sum += (p[3] + p[2] + p[1] + 2 * p[0]); else sum += (p[3] + 3 * p[1] + p[0]); n = 0; } else { if(p[n - 2] - 2 * p[1] + p[0] <= 0) sum += (p[n - 1] + p[n - 2] + 2 * p[0]); else sum += (p[n - 1] + 2 * p[1] + p[0]); n -= 2; } } cout<<sum<<endl; } return 0; }