b_lc_最大平均通过率(多路归并思想)
给一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
给你一个整数 extraStudents ,表示额外有 extraStudents 个学生一定 能通过任何班级的期末考。给这 extraStudents 个学生每人都安排一个班级,**使得 所有 班级的 平均 通过率 最大 **。
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。(n<1e5)
思路:让一个有a个学生中b个通过的班级增加一个聪明学生后的通过率的增量为\(\cfrac{b+1}{a+1}\)-\(\cfrac{b}{a}=\cfrac{a-b}{a(a+1)}\),a越大,增量越少,故可得不断地给同一个班级添加学生,这个班级通过率增量会减少,故可以用堆来维护多个班级的增量的最大值,每次往增量最大的那个班级添加聪明的学生(也就是大顶堆堆顶班级)
struct node {
int a, b;
double v; //按照增量排序
bool operator<(const node& o) const {
return v < o.v;
}
};
class Solution {
public:
double maxAverageRatio(vector<vector<int>>& classes, int m) {
int n=classes.size();
double s=0;
priority_queue<node, vector<node>> q;
for (auto& c : classes) {
int a=c[1], b=c[0];
s+=(double)b/a;
q.push({a, b, (a-b)/(a*(a+1.0))});
}
while (m--) {
auto t=q.top(); q.pop();
int a=t.a+1, b=t.b+1;
s+=t.v;
q.push({a, b, (a-b)/(a*(a+1.0))});
}
return s/n;
}
};