POJ

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场比赛,第i场能做出ai道题,第i场比赛有b道题。有公式100*Σ ai / Σ bi计算一个值x,现在要求删去k场比赛后使得100*Σ ai / Σ bi值最大。
01分数规划入门题。根据计算公式可推出 不等式Σ ai / Σ bi ≥ x ,移项后得到Σ ai - Σ bi *x ≥0,二分满足条件的x值,使得求和结果最大即可。

#include<stdio.h>///01分数规划
#include<algorithm>
using namespace std;///题目要求Σ ai / Σ bi 值最大,那么有不等式 Σ ai / Σ bi ≥ x 即这个最大值x是所求
const int maxn=1e3+8;///不等式可以化为   Σ ai ≥ Σ bi *x  ---->   Σ ai - Σ bi *x ≥0  那么计算Σ ai - Σ bi *x 的值 判断求和前n-k个结果是否大于等于0,
const double eqs=1e-6;///大于等于0表示符合条件,我们向后二分更大的x,即二分答案,也就是正确删除k个的情况下获得更大的x
int a[maxn],b[maxn];///否则若求和结果小于0,说明不等式不成立,选择的最大值太大,ai无法满足
double mx[maxn];
int n,k;
bool judge(double x)///二分最大值
{
    for(int i=1;i<=n;i++)mx[i]=a[i]-x*b[i];
    sort(mx+1,mx+1+n);
    double ans=0;
    for(int i=n;i>k;i--)ans+=mx[i];///取前n-k个最大值算出来的数
    return ans>=0;
}
int main()
{
    while(scanf("%d%d",&n,&k)&&(n||k))
    {
        for(int i=1; i<=n; i++)scanf("%d",&a[i]);
        for(int i=1; i<=n; i++)scanf("%d",&b[i]);
        double l=0,r=1;
        while(r-l>eqs)
        {
            double mid=(l+r)/2;
            if(judge(mid))l=mid;
            else r=mid;
        }
        printf("%.0f
",l*100);
    }
}
原文地址:https://www.cnblogs.com/kuronekonano/p/11135716.html