Dropping tests POJ - 2976 最大化平均值。

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 npositive 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次考试,每次考试有 b[i]个题目,但是知道每次能作出的 题目 a[i], 然后要求去掉 k 个,求得到的  a/b*100 最大;

这个就是最大化平均值,就是挑战书上的P143,选出K个物品使得单位重量的价值最大。都是一个思路。

先枚举 x ,,就是结果,

然后 根据  a-x*b 从大到小排序,选出要拿的物品。结果大于等于0就可行。

具体证明看书上。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1009;
struct node{
    int a,b;
}p[MAXN];
int n,k;
double y[MAXN];

bool judge(double x){
    x = x/100;
    for (int i = 0; i < n; i++)
        y[i] = p[i].a - x*p[i].b;
    sort(y,y+n);
    double tot = 0;
    for (int i = n-1; i > k-1; i--){
        tot += y[i];
    }
    if (tot >= 0) return 1; else return 0;
}

int main() {
    while(scanf("%d%d",&n,&k)==2) {
        if (n == 0) break;

        for (int i = 0; i < n; i++)
            scanf("%d", &p[i].a);
        for (int i = 0; i < n; i++)
            scanf("%d", &p[i].b);
        double l = 0, r = 100,mid;
        while(r-l > 0.0001){
            mid = (l + r)/2;
            if (judge(mid)) l = mid; else r = mid;
        }
        int ans;
       // printf("%.5lf  ",l);
        ans = (l+0.5);
        printf("%d\n",ans);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/80262485
今日推荐