Dropping tests
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 13793   Accepted: 4838

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

POJ 2976 Dropping tests.

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 POJ 2976 Dropping tests. However, if you drop the third test, your cumulative average becomes POJ 2976 Dropping tests.

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

题目大意:一个序列,每个数有两个属性,ai和bi,求去掉k个数后的sum{ai}/sum{bi}最大

题解:01分数规划

设答案为t,若存在sigma ai/ sigma bi >t,那么答案还可以继续扩大。

将公式变形,sigma ai>t*sigma bi,sigma (ai-t*bi)>0,令si=ai-t*bi,然后排序,去掉k个小的后的

sigma si是否大于0,若是则答案还可以继续扩大,否则缩小。

代码:

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 1009
using namespace std;

int n,k;
double l,r,mid,a[maxn],b[maxn],s[maxn];
double eps=1e-7;

bool check(double p){
    for(int i=1;i<=n;i++)s[i]=a[i]-p*b[i];
    sort(s+1,s+n+1);double all=0.;
    for(int i=n;i>k;i--)all+=s[i];
    return all>0;
}
int main(){
    while(1){
        scanf("%d%d",&n,&k);
        if(!n&&!k)break;
        for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
        for(int i=1;i<=n;i++)scanf("%lf",&b[i]);
        l=0;r=1;
        while(r-l>eps){
            mid=(l+r)/2.;double all=0.;
            if(check(mid))l=mid;
            else r=mid;
        }
        printf("%.0lf\n",l*100);
    }
    return 0;
} 

 

 

 

 

相关文章: