排队打水

问题描述

(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;
}