链接:https://www.nowcoder.com/acm/contest/143/A
来源:牛客网
Kanade selected n courses in the university. The academic credit of the i-th course is s[i] and the score of the i-th course is c[i].
At the university where she attended, the final score of her is
Now she can delete at most k courses and she want to know what the highest final score that can get.
输入描述:
The first line has two positive integers n,k
The second line has n positive integers s[i]
The third line has n positive integers c[i]
输出描述:
Output the highest final score, your answer is correct if and only if the absolute error with the standard answer is no more than 10
-5
备注:
1≤ n≤ 10
5
0≤ k < n
1≤ s[i],c[i] ≤ 10
3
题意:给定 n 门课以及它们的学分和绩点,定义总绩点是所有课的加权平均数,给定一个数 k, 你可以删除最多 k 门课,求你的总绩点最大能到多少 1 <=n <=10^5
分析:假设最大总绩点为D,则题中式子可以转化成∑s[i](c[i]-D)=0
观察式子容易看出这是一个分数规划问题,我们可以通过二分D来解答,使左边式子结果最接近0的D即是最大总绩点D
以后类似的分数或者方程式不等式求解问题都可以用这种方式求解
01分数参考博客:https://blog.csdn.net/hhaile/article/details/8883652
AC代码:
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define ls (r<<1) #define rs (r<<1|1) #define debug(a) cout << #a << " " << a << endl using namespace std; typedef long long ll; const ll maxn = 1e5 + 10; const ll mod = 1e9 + 7; ll s[maxn], c[maxn], n, k; double le, ri, t[maxn]; bool check( double x ) { for( ll i = 1; i <= n; i ++ ) { t[i] = s[i]*(c[i]-x); } sort( t+1, t+n+1 ); double tmp = 0.0; for( ll i = k+1; i <= n; i ++ ) { tmp += t[i]; } return tmp>0; } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin >> n >> k; for( ll i = 1; i <= n; i ++ ) { cin >> s[i]; } for( ll i = 1; i <= n; i ++ ) { cin >> c[i]; ri = max( ri, (double)c[i] ); } double mid; while( ri-le > 1e-6 ) { mid = (le+ri)/2; //debug(mid); if( check(mid) ) { le = mid; } else { ri = mid; } } printf("%.10lf ",mid); return 0; }