POJ - 2976 Dropping tests(二分 + 01分数规划)

来源:互联网 发布:java工程师和架构师 编辑:程序博客网 时间:2024/06/10 19:37
Dropping tests
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 9635 Accepted: 3368

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 15 0 25 1 64 21 2 7 95 6 7 90 0

Sample Output

83100

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).

此题可以使用01分数规划来处理,此代码用公式推导:



如此可以发现a[i]-x*b[i]是个积性函数即单调函数就可以使用二分然后我们对每一个x,进行a[i]-x*b[i]排序,取其中的n-k判断他们的和是否大于等于0.

#include <cstdio>#include <cstring>#include <algorithm>#include <functional>using namespace std;const int MAXN = 1e3 + 5;const double eps = 1e-10;int n, k;struct o {double a, b;o() {}o(double a, double b):a(a),b(b) {}bool operator < (const o &p) const {return b - a > p.b - p.a;}} O[MAXN];double A[MAXN];bool C(double m) {double z = 0;for(int i = 0; i < n; i ++) {A[i] = O[i].a - m * O[i].b;}sort(A, A + n, greater<int>());for(int i = 0;i < n - k;i ++) z += A[i];return z >= 0;}int main() {while(~scanf("%d%d", &n, &k), n || k) {for(int i = 0; i < n; i ++) {scanf("%lf", &O[i].a);}for(int i = 0; i < n; i ++) {scanf("%lf", &O[i].b);}double lb = 0, ub = 1.;for(int i = 0; i < 100; i ++) {double mid = (ub + lb) / 2.;if(C(mid)) {lb = mid;} else {ub = mid;}}printf("%.0f\n", ub * 100);}return 0;}


1 0
原创粉丝点击