题目:
思路:
题目求最大平均通过率,因为班级总数不变,所以就是求最大总通过率
设通过率增量为
- 也就是每个优秀学生都要塞到通过率增量最大的那个班,实现局部最优
- 因此我们可以用优先队列维护一个通过率增量从大到小排序的大顶堆
- 循环extraStudents次,每次取出最优班级,并把优等生塞进去,然后重新入队
- 这样能保证每次都让通过率最大化,因此总通过率也就最大化
class Solution {
public double maxAverageRatio(int[][] classes, int extraStudents) {
PriorityQueue<double[]> q=new PriorityQueue<>((a,b)->{
double x=(a[0]+1)/(a[1]+1)-a[0]/a[1];
double y=(b[0]+1)/(b[1]+1)-b[0]/b[1];
if(x==y) return 0;
return y>x? 1:-1;
}); //按通过率增量排序的大顶堆
for(int[] x:classes) q.offer(new double[] {x[0],x[1]});
while(extraStudents-->0)
{
var t=q.poll(); //每次都取出通过率增量最大的 这样能保证把这个优秀生塞进去最优
double a=t[0]+1;
double b=t[1]+1;
q.offer(new double[] {a,b}); //把塞进去的结果重新入队
}
double res=0;
while(!q.isEmpty())
{
var t=q.poll();
res+=t[0]/t[1];
}
return res/classes.length;
}
}