题目链接:http://poj.org/problem?id=2976
Dropping tests
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 17838 | Accepted: 6186 |
Description
In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be
.
Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.
Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is . However, if you drop the third test, your cumulative average becomes .
Input
The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, 1 ≤ n ≤ 1000 and 0 ≤ k < n. The second line contains n integers indicating ai for all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that 0 ≤ ai ≤ bi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case with n = k = 0 and should not be processed.
Output
For each test case, write a single line with the highest cumulative average possible after dropping k of the given test scores. The average should be rounded to the nearest integer.
Sample Input
3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0
Sample Output
83 100
Hint
To avoid ambiguities due to rounding errors, the judge tests have been constructed so that all answers are at least 0.001 away from a decision boundary (i.e., you can assume that the average is never 83.4997).
Source
题目概述:
N个物品,每个物品 i 有 a[ i ] 和 b[ i ] 两种属性,去掉K个物品,是的 Σai / Σbi 最大。
解题思路:
我们令 Σai / Σbi >= x, 然后二分x,而判断条件则移一下项得 Σai >= Σbi*x → Σai - Σbi*x >= 0,因为我们要去掉 K 个小的, 取N-K个使结果最大化的,所以用 令 p[ i ] = Σai - Σbi*x,对 p[ i ] 默认升序排序之后,第 K 到 N 个。判断这些数和是否满足不等式条件(大于等于0)
注意事项:
因为计算机的精度问题,要注意细节的处理,对浮点数的计算。(in代码)
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define INF 0x3f3f3f3f 7 #define ll long long int 8 using namespace std; 9 10 const int MAXN = 2048; 11 int N, K; 12 int a[MAXN], b[MAXN]; 13 double p[MAXN]; ///这里的p一定要是浮点型,因为本来就是计算分式 14 15 bool ok(double x) 16 { 17 for(int i = 1; i <= N; i++) 18 { 19 p[i] = a[i]-b[i]*x; 20 } 21 sort(p+1, p+N+1); 22 double ans = 0; 23 for(int j = N; j > K; j--) 24 { 25 ans+=p[j]; 26 } 27 return ans>=0; 28 } 29 30 int main() 31 { 32 while(~scanf("%d%d", &N, &K) && N|K) 33 { 34 for(int i = 1; i <= N; i++) 35 { 36 scanf("%d", &a[i]); 37 } 38 for(int i = 1; i <= N; i++) 39 { 40 scanf("%d", &b[i]); 41 } 42 double l = 0, r = 1; 43 while(r-l>1e-6) //!!!这里不用0,是因为计算机精度问题,计算浮点数要保留一定误差,改成0会超时 44 { 45 double mid = (l+r)/2.0; 46 if(ok(mid)) l = mid; 47 else r = mid; 48 } 49 printf("%.0lf ", l*100); 50 } 51 return 0; 52 }