1 条题解
-
0
练85.2 排队接水
解题思路
将人按取水时间升序排序,平局按原编号。某人等待的是前面所有人的取水总时长,维护前缀和累计等待,再除n。
正确性说明
若相邻两人取水耗时x>y且x在前,交换后二者之后人的等待不变,二者等待之和减少x-y,因此最优顺序不存在长任务在短任务前的逆序。
易错点
等待不含自己的取水时间;样例有相同时间,原编号作固定平局规则。
复杂度
时间O(n log n),空间O(n)。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<pair<long long, int>> a(n); for (int i = 0; i < n; i++) { cin >> a[i].first; a[i].second = i + 1; } sort(a.begin(), a.end()); long long prefix = 0, total = 0; for (int i = 0; i < n; i++) { if (i) cout << " "; cout << a[i].second; total += prefix; prefix += a[i].first; } cout << "\n" << fixed << setprecision(2) << double(total) / n << "\n"; return 0; }
- 1