排队打水

问题描述

\(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;
}
posted @ 2021-03-03 12:44  0x7F  阅读(66)  评论(0编辑  收藏  举报