题目描述
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≤ 105
0≤ k < n
1≤ s[i],c[i] ≤ 103
思路:不能将成绩最差的k门课去掉,因为一门课拖后腿的程度不仅与它的分数有关,也与它的学分多少有关,比如两门课,一门60,一门59,不能就说59的那门课拖后腿更多,如果59的那门课只占一个学分,而60的那门课占5个学分,那就不一样了;
但要肯定的是,尽可能去掉更多的课,所以要使结果最优要去掉k门课;可以考虑二分枚举答案(gpa),计算出每门课对应的s*c-s*gpa,取该结果最高的n-k门课并求和,若>=0,则该gpa可以达到;
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> typedef long long ll; using namespace std; struct Course{ ll s,c; }course[100010]; double b[100010]; ll n,k; bool ok(double a){ for(ll i=1;i<=n;i++) b[i]=course[i].s*course[i].c*1.0-course[i].s*a*1.0; sort(b+1,b+1+n); double sum=0; for(ll i=n;i>=k+1;i--) sum+=b[i]; return sum>=0; } int main() { scanf("%lld%lld",&n,&k); for(ll i=1;i<=n;i++) scanf("%lld",&course[i].s); for(ll i=1;i<=n;i++) scanf("%lld",&course[i].c); double L=0,R=1000.0; while(R-L>1e-6){ double mid=(L+R)*1.0/2.0; if(ok(mid)) L=mid; else R=mid; } printf("%.6f ",R); return 0; }