题意:
n≤1000个人要过桥,每次要有手电筒才能过桥,只有一个手电筒
过桥时间为最慢的那个人的世间,每次只能过1个或者2个,问最小过桥时间和方案
分析:
先从简单的问题开始分析,排序是显然的,肯定先送大的
1个人:直接过去时间a[1]
2个人:直接过去时间a[2]
3个人:从小到大为ABC,两种方案,AB,A,AC|AC,A,AB,时间都是a[1]+a[2]+a[3]
4个人:左边两个为AB,最大的两个为YZ
AB,A,YZ,B,(AB) | AZ,A,AY,A,(AB),发现形成了循环,最小的两个人可以复用
这俩时间分别为B+A+Z+B,Z+A+Y+A,需要比较一下
发现对于n>3的情况都可以不断n−2将问题规模缩小
代码:
//
// Created by TaoSama on 2015-11-06
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, a[1005];
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
int t; scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", a + i);
sort(a + 1, a + 1 + n);
if(n == 1) printf("%d\n%d\n", a[1], a[1]);
else if(n == 2) printf("%d\n%d %d\n", a[2], a[1], a[2]);
else if(n == 3) {
//AB, A, AC | AC, A, AB
printf("%d\n", a[1] + a[2] + a[3]);
printf("%d %d\n%d\n", a[1], a[2], a[1]);
printf("%d %d\n", a[1], a[3]);
} else {
//AB, A, YZ, B, (AB) | AZ, A, AY, A, (AB)
int ans = 0;
for(int i = n; i >= 4; i -= 2)
ans += min(2 * a[2] + a[1] + a[i], a[i] + a[i - 1] + 2 * a[1]);
if(n & 1) ans += a[1] + a[2] + a[3];
else ans += a[2];
printf("%d\n", ans);
for(int i = n; i >= 4; i -= 2) {
if(3 * a[2] + a[1] + a[i] > a[i] + a[i - 1] + 2 * a[1] + a[2]) {
printf("%d %d\n%d\n", a[1], a[i], a[1]);
printf("%d %d\n%d\n", a[1], a[i - 1], a[1]);
} else {
printf("%d %d\n%d\n", a[1], a[2], a[1]);
printf("%d %d\n%d\n", a[i - 1], a[i], a[2]);
}
}
if(n & 1) {
printf("%d %d\n%d\n", a[1], a[2], a[1]);
printf("%d %d\n", a[1], a[3]);
} else printf("%d %d\n", a[1], a[2]);
}
if(t) puts("");
}
return 0;
}