G - 过河
题目描述
UCAS_ACM小组的N名成员外出旅游,结果在路上碰到了一条河,岸边只有一艘船,这艘船最多只能载两人。
已知N名成员每人有一个过河时间ti,每次划船过河的时间等于船上成员的过河时间的最大值。请你找N名成员全部到底对岸的最少耗时。
输入
输入包含多组测试数据。第一行含有一个正整数T,表示数据组数。
每组数据的第一行含有一个整数N。接下来的一行含有N个整数,表示ti。
输出
对于每组输入数据输出一行,每行包括1个整数,代表该组数据下到对岸的最少耗时。
样例输入
2
4
1 2 5 10
5
1 2 8 7 6
样例输出
17
22
数据范围
1≤T≤20
1≤N≤1000
1≤ti≤100
提示
船划到对岸后不会自动飘回来的哦~
因为两个人中,过河时间是算慢的那个人,我们肯定是用尽可能少的时间送走时间长的人,先把时间排个升序。
A,B......C,D
B......C A,D //最快的把最慢的送走,花费的时间是D
A,B......C D //最快的回来,花费的时间是A
B...... A,C,D//最快的把次慢的送走,花费的时间是C
A,B...... C,D //最快的回来,花费的时间是A
总花费:2A+C+D
这样我们就把最慢的两个人送走了,可是还有一种方法:
A,B......C,D
......C,D A,B //最快的和最慢的过来,花费的时间是B
A......C,D B //最快的回来,花费的时间是A
A...... B,C,D//最慢的和次慢的过来,花费的时间是D
A,B...... C,D //次快的回去,花费的时间是B
总花费:A+2B+D
然后我们比较一下两者的大小,取最小就行了。
AC代码
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1100;
int main(void)
{
int a[maxn];
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
int ans = 0;
while (n > 3)
{
ans += min(2 * a[1] + a[n] + a[n - 1], a[1] + 2 * a[2] + a[n]);
n -= 2;
}
if (n == 1)
ans += a[1];
else if (n == 2)
ans += a[2];
else
ans += a[1] + a[2] + a[3];
cout << ans << endl;
}
return 0;
}
可是我第一遍的时候没有排序,居然也过了,很神奇,可能是OJ平台测试数据不太行。