LeetCode 1792. 最大平均通过率(堆)

题意:
一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。
给你一个二维数组 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
解法:
因为班级数量是固定的,最大化平均通过率其实就是最大化总通过率.

对于(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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值