排队打水
问题描述
有 \(n\) 个人排队到 \(1\) 个水龙头处打水,第 \(i\) 个人装满水桶所需的时间是 \(t_i\),请问如何安排他们的打水顺序才能使所有人的等待时间之和最小?
问题分析
各时间为:\(t_1, t_2, \ ... \ t_n\)
总等待时间为:\(t_1 * (n - 1) + t_2 * (n - 2) + ... + t_n * 0\)
时间越小越先进行为最优解
证明: 假设\(t_i < t_{i+1}\), 显然 \(t_{i+1} * (n - i) + t_i * (n - i - 1) > t_i * (n - i) + t_{i+1} * (n - i - 1)\)。 而且\(t_i\)和\(t_{i+1}\)的交换对其它计算并没有影响,所以首先进行时间较小的能够获得最优解
代码实现
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; ++ i) cin >> a[i];
sort(a, a + n);
LL res = 0;
for (int i = 0; i < n; ++ i) res += a[i] * (n - i - 1);
cout << res << endl;
return 0;
}