1792. 最大平均通过率

题目链接:1792. 最大平均通过率

方法:优先队列

解题思路

(1)为了使得平均通过率最大化,应使得所有班级的总通过率最大,那么 \(extraStudents\) 学生应该使得某一个班级的通过率增加量最大,才添加到该班级中。因此可以使用优先队列,确定优先级,每次为 \(q.top()\) 的班级添加学生,直到 \(extraStudents == 0\) 为止。
(2)现假设先有一个班级 \(a\),则为 \(a\) 班级增加一名 \(extraStudents\) 学生的通过率增加量为 \(\frac{a.pass + 1}{a.total + 1}\) - \(\frac{a.pass}{a.total}\)。那么对于增加一名通过学生,班级 \(a\) 通过率增加量 < 班级 \(b\) 通过率增加量可以表示为 \(\frac{a.pass + 1}{a.total + 1}\) - \(\frac{a.pass}{a.total}\) \(<\) \(\frac{b.pass + 1}{b.total + 1}\) - \(\frac{b.pass}{b.total}\) \(<=>\) \(b.total\) \(\times\) \((b.total + 1)\) \(\times\) \((a.total - a.pass)\) \(<\) \(a.total\) \(\times\) \((a.total + 1)\) \(\times\) \((b.total - b.pass)\)

代码

class Solution {
public:
    struct node {
        int pass, total;
        // 优先队列重载'<'运算符,要想建立大根堆,应该使用'a' < 'b',其中的a 和 b是广泛的。
        friend bool operator < (const node& a, const node& b) {
            return (long long) (b.total + 1) * b.total * (a.total - a.pass) < (long long) (a.total + 1) * a.total * (b.total - b.pass);
        }
    };
    double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
        priority_queue<node> q;
        for (auto &c : classes) q.push({c[0], c[1]});
        while (extraStudents -- != 0) {
            node temp = q.top();
            q.pop();
            q.push({temp.pass + 1, temp.total + 1});
        }
        double ans = 0.0;
        while (!q.empty()) {
            node temp = q.top();
            q.pop();
            ans += 1.0 * temp.pass / temp.total;
        }
        return ans / classes.size();
    }
};

复杂度分析

时间复杂度:\(O((n + m)logn)\)\(n\) 为班级数,\(m\)\(extraStudents\) 数;
空间复杂度:\(O(n)\)

posted @ 2023-04-08 01:45  lixycc  阅读(33)  评论(0)    收藏  举报