本题类似于题目:POJ 1700 经典过河问题
这是一道经典的过河问题,使用贪心算法。有两种策略:
- 最快的(即所用时间t[0])和次快的过河,然后最快的将船划回来,再次慢的和最慢的过河,然后次快的将船划回来。
即所需时间为:t[0]+2*t[1]+t[n-1]
- 最快的和最慢的过河,然后最快的将船划回来,再最快的和次慢的过河,然后最快的将船划回来。
即所需时间为:2*t[0]+t[n-2]+t[n-1]
每次过河都比对两种方案,选花费最小的,保证耗时最少。
另外,当只有人数n <= 2
时,直接返回t[t.size() - 1]
即可。
个人感觉,这道题的贪心有点特别,需要从两种方案里面选一种最好的,之前碰到的贪心问题,都是一种方案一走到底,所以在这儿没有想到,以后要注意。
代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int T, n;
cin >> T;
while (T--) {
cin >> n;
vector<int> tt(n);
for (int i = 0; i < n; ++i) {
cin >> tt[i];
}
if (n <= 2) {
cout << tt[tt.size() - 1] << endl;
continue;
}
sort(tt.begin(), tt.end());
long cost = 0, cost1 = 0, cost2 = 0;
int m = 0;
for (m = tt.size(); m > 3; m -= 2) {
cost1 = tt[0] + 2 * tt[1] + tt[m - 1];
cost2 = 2 * tt[0] + tt[m - 2] + tt[m - 1];
cost += cost1 < cost2 ? cost1 : cost2;;
}
if (3 == m) cost += tt[0] + tt[1] + tt[2];
if (2 == m) cost += tt[1];
cout << cost << endl;
}
return 0;
}