POJ2976Dropping tests(二分)

题目链接:

http://poj.org/problem?id=2976


题意:

给定大小为n的两个数组a,b;

设 ans = sigma{ a[i] / b[i] .1 <= i <= n};

我们可以去掉其中的k个,求ans的最大值


分析:

设这个最大值 为 x;

    sigma{ a[i ] /b[i ]} > = x

=>sigba{ a[i] } > = sigma{ b[i] } *x;

=>sigba{ a[i] - b[i] * x } >=0;

设 c [i] = a[i] - b[i] *x;

我们可以对c[i]进行排序然后去掉前k个.

然后判断剩下的sum是否大于0.

然后可以二分x得到答案。


代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1010;
const double eps = 1e-5;

int k,n;

double a[maxn],b[maxn];
double c[maxn];

bool calu(double x){
    double sum = 0;
    for(int i=0;i<n;i++){
        c[i] = a[i]-b[i]*x;
        sum+=c[i];
    }
    sort(c,c+n);
    for(int i=0;i<k;i++)
        sum -=c[i];
    return sum>=0;
}

int main()
{
    while(~scanf("%d%d",&n,&k)){
        if(n==0&&k==0) break;
        for(int i=0;i<n;i++)
            scanf("%lf",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%lf",&b[i]);
        double l= 0,r=1.0,mid;
        while(l+eps<r){
            mid =  (l+r)/2.0;
            //cout<<"mid "<<mid<<endl;
            if(calu(mid)) l=mid;
            else r = mid;
        }
        int tmp = r*100+0.5;
        printf("%d\n",tmp);
    }
    return 0;
}



你可能感兴趣的:(POJ2976Dropping tests(二分))