给定一个班级数组,每个班级包括总人数和通过人数。现在可以加入k
个通过的学生到任意班级,求
最大的平均通过率。
假设某一班级总人数为m
, 通过人数为n
,则加入一个通过的学生对通过率的增加
d
i
f
f
diff
diff为
n + 1 m + 1 − n m = m − n m ( m + 1 ) \frac{n+1}{m+1} - \frac{n}{m} = \frac{m -n}{m(m + 1)} m+1n+1−mn=m(m+1)m−n
我们可以通过维护班级的 d i f f diff diff值的最大堆来解决这个问题。
由于 0 ≤ n ≤ m ≤ 1 e 5 0 \le n \le m \le 1e5 0≤n≤m≤1e5
在比较两个班级的 d i f f diff diff值的时候可以换为乘法
即判断
(
m
0
−
n
0
)
∗
m
1
(
m
1
+
1
)
<
(
m
1
−
n
1
)
∗
m
0
(
m
0
+
1
)
(m_0 - n_0) *m_1(m_1 + 1) < (m_1 - n_1) * m_0 (m_0+1)
(m0−n0)∗m1(m1+1)<(m1−n1)∗m0(m0+1)
的布尔值即可
class Solution {
struct classRate {
classRate(int a,int b):pass(a),total(b) {
}
bool operator <( const classRate &b) const{
long long a1 = 1ll * (total - pass) * (b.total) * (b.total + 1);
long long a2 = 1ll * (b.total - b.pass) * (total) * (total + 1);
return a1 < a2;
}
int total;
int pass;
};
public:
double
maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
std::priority_queue<classRate> rPq;
for(auto &v:classes) {
classRate elm(v[0], v[1]);
rPq.push(elm);
}
int i = 0;
while (i < extraStudents) {
classRate cur = rPq.top();
rPq.pop();
cur.total += 1;
cur.pass += 1;
rPq.push(cur);
i++;
}
double res = 0;
while (!rPq.empty()) {
classRate cur = rPq.top();
rPq.pop();
res += (double) cur.pass / cur.total;
}
return res/classes.size();
}
};