N 人需過河,唯一小船每次最多載 2 人,划槳速度以較慢者為準。求所有人過河的最短總時間。
排序後設 a[0] ≤ a[1] ≤ … ≤ a[n-1]。每次處理最慢的兩人 a[n-1], a[n-2],有兩種可行策略:
a[0] + 2*a[1] + a[n-1]a[0],a[1] 過河 → a[0] 回 → a[n-2],a[n-1] 過河 → a[1] 回。
2*a[0] + a[n-2] + a[n-1]a[0],a[n-1] 過河 → a[0] 回 → a[0],a[n-2] 過河 → a[0] 回。
每輪取兩者較小值,將問題規模減 2,直到剩 ≤ 3 人直接處理。
n == 1:a[0]n == 2:a[1]n == 3:a[0] + a[1] + a[2](最快陪同兩人各過一次)#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T; cin >> T;
while (T--) {
int n; cin >> n;
vector a(n);
for (int &x : a) cin >> x;
sort(a.begin(), a.end());
long long ans = 0;
while (n > 3) {
long long cost1 = a[0] + 2LL*a[1] + a[n-1];
long long cost2 = 2LL*a[0] + a[n-2] + a[n-1];
ans += min(cost1, cost2);
n -= 2;
}
if (n == 1) ans += a[0];
else if (n == 2) ans += a[1];
else if (n == 3) ans += a[0] + a[1] + a[2];
cout << ans << "\n";
}
return 0;
}
O(N log N)(排序主導),空間 O(N)。