F - Dropping tests POJ - 2976(二分)

 
F - 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 n positive integers indicating bi for all i. It is guaranteed that 0 ≤ aibi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case with n = k = 0 and should not be processed.

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

题意:最大化平均值。

分析:本来以为按照每个的单位价值排序然后贪心可以去的最大值,实际操作后连样例都过不了,仔细分析之后发现当每个物体的单位价值是相对独立的。。。。。。

看了小白书之后发现是一道二分的经典例题。。。。改用二分来做,一直wa,判断出现了错误,题目中说的是当n和k都为0的时候结束,错误的把判断写成了只要有一个为0就结束。。。wa了8次。。。。;;;;;;;;思路还是二分的思路,最后公式为c(x)=((ai-x*bi)从大到小排列的前(n-k)个的和不小于0)。

证明:见小白书的P144

收获:刚开始学习二分,慢慢开始感觉到二分的强大啊。

while里循环的小数点的后几位取决于题目要求的精度。

AC:

#include 
#include 
#include 
using namespace std;

const int maxn=10000+50;
const int INF = 1000000+50;
int w[maxn],v[maxn];

int n,k;
int judge(double x)
{
    double y[maxn];
    for(int i=0; i=0;
}
void solve()
{
    double lb=0,ub=INF;
    while(ub-lb>0.0001)
    {
        double mid=(lb+ub)/2;
        if(judge(mid)) lb=mid;
        else ub=mid;
    }
    printf("%.0f\n",lb*100);
}
int main ()
{
    while(scanf("%d%d",&n,&k)  )
    {
        if(!n&&!k)break;
        for(int i=0; i


你可能感兴趣的:(二分,挑战程序设计竞赛)