Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7828 | Accepted: 2739 |
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).
题意:给你N个二元组(a[i], b[i]),你可以从里面任意去掉K个。问你100 * sigma(a[i]) / sigma(b[i])的最大值。
以前做过一道类似的题目 ,看了别人题解AC之后就放那里了。现在看最小割,也用到分数规划,没办法只好看了。
分析:我们假设存在一种方案使得 o = sigma(a[i]) / sigma(b[i]) 的值 是最大的,我们可以转化这个式子并新设一个函数——sigma(t[i]) = sigma(a[i]) - sigma(b[i]) * o 。
切记,我们假设最大的o = sigma(a[i]) / sigma(b[i])才新设函数t[i]的。
这样的话,当o取最大值时,会满足sigma(t[i]) = 0。
反过来说sigma(t[i]) > 0时,说明当前的o不是最大的,还可以继续增大。
sigma(t[i]) < 0 时,说明当前的o过大,是不能满足的。
思路:二分枚举o的值,用当前的o值求出所有的t[i],累加最大的N-K个,判断这N-K个t[i]的值是否大于0。若大于0继续增大o值,小于o则减小o值。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define eps 1e-8 #define MAXN 1010 using namespace std; int N, K; double a[MAXN], b[MAXN]; double t[MAXN]; bool judge(double o) { for(int i = 0; i < N; i++)//求t[i] t[i] = a[i] - o * b[i]; sort(t, t+N);//排序后 double sum = 0; for(int i = K; i < N; i++)//累加最大的N-K个 sum += t[i]; return sum >= 0; } int main() { while(scanf("%d%d", &N, &K), N||K) { for(int i = 0; i < N; i++) scanf("%lf", &a[i]); for(int i = 0; i < N; i++) scanf("%lf", &b[i]); double l = 0, r = 1; while(r - l >= eps) { double mid = (l + r) / 2; if(judge(mid)) l = mid; else r = mid; } printf("%.0lf\n", l * 100); } return 0; }