LeetCode 1792. Maximum average pass rate (heap)

Title:

一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。
给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,
表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。

给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。
你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。

一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。
平均通过率 是所有班级的通过率之和除以班级数目。

请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。
与标准答案误差范围在 1e-5 以内的结果都会视为正确结果。

数据范围:
1 <= classes.length <= 1e5
classes[i].length == 2
1 <= passi <= totali <= 1e5
1 <= extraStudents <= 1e5

solution:

因为班级数量是固定的,最大化平均通过率其实就是最大化总通过率.

对于(x,y),加一个学生之后变成(x+1,y+1),通过率的变化量为(x+1)/(y+1)-x/y.
用一个堆存所有二元组(x,y),每次贪心地取出变化量最大的出来即可.

原理是每次添加之后,下一次添加的变化量一定会比这次小,所以每次用堆选出变化量最大的.

code:

struct PI{
    
    
    int x,y;
    bool operator<(const PI &t)const{
    
    
        double a=(x+1)*1.0/(y+1)-x*1.0/y;
        double b=(t.x+1)*1.0/(t.y+1)-t.x*1.0/t.y;
        return a<b;
    }
};
class Solution {
    
    
public:
    double maxAverageRatio(vector<vector<int>>& e, int p) {
    
    
        priority_queue<PI>q;
        for(auto i:e){
    
    
            q.push({
    
    i[0],i[1]});
        }
        while(p--){
    
    
            PI x=q.top();q.pop();
            x.x++,x.y++;
            q.push(x);
        }
        double ans=0;
        while(q.size()){
    
    
            PI x=q.top();q.pop();
            ans+=(x.x)*1.0/x.y;
        }
        ans/=(int)e.size();
        return ans;
    }
};

Guess you like

Origin blog.csdn.net/weixin_44178736/article/details/114822122