堆(优先队列)
参考:分享丨【算法题单】常用数据结构(前缀和/栈/队列/堆/字典树/并查集/树状数组/线段树) - 讨论 - 力扣(LeetCode)
一、基础
Leetcode 1792. 最大平均通过率
思路:
错误思路,贪心全加到通过率最差的班级?×,应从数学的角度,考虑每增加一个必过的学生,带来的增量是多少?可以先举一个具体的例子,发现规律并加以证明即可。
具体做法,
Code:
class Solution { public:double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {using DII = tuple<double, int, int>;auto cmp = [](const DII& a, const DII& b) {return get<0>(a) < get<0>(b); // 比较下一个学生带来的增量大小,降序}; // lesspriority_queue<DII, vector<DII>, decltype(cmp)> pq; // 大顶堆()for (auto& c: classes) {int a = c[0], b = c[1];pq.emplace(1.0 * (b - a) / (1LL* b * (b + 1)), a, b);} while (extraStudents --) {auto [_, a, b] = pq.top();pq.pop();a ++, b ++;pq.emplace(1.0 * (b - a) / (1LL* b * (b + 1)), a, b);}double sum = 0;int n = pq.size();while (! pq.empty()) {auto [_, a, b] = pq.top();pq.pop();sum += 1.0 * a / b;} return sum / n;} };