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;
    }
};
原文地址:https://www.cnblogs.com/wdt1/p/14534310.html