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)\)。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号