POJ2976:Dropping tests(二分法)

将得到的分数存在a[] 数组里,将原总分存在b[] 数组里。


要求的是100*(∑ai)/(∑bi) 的最大值,嗯。。。是去掉k对数据之后。


用二分,就需要确定一个mid , 假定  100*(∑ai)/(∑bi) = mid .等价于   100*∑ai = mid *∑bi   等价于   100*∑ai - mid *∑bi =0  将求和符合提前,得到   ∑100*ai - ∑mid *bi =0

合并一下   ∑(100*a - mid *bi)=0


这样,只要mid 满足这个式子,那么就是满足原式的,也就是说,mid是通过那个式子求出来的,这样,只要将每队,根据  100*a - mid *bi进行排序,然后去除最小的k个,后面的所有求和,和为零,那么mid即为所求。通过二分算法举出mid即可。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

int N,k;
double a[1005],b[1005];//接收输入
double c[1005];//算出来的……
double sum;

bool solve()//判断去掉k个的时候,所达到的结果是否满足公式
{
    sum = 0.0;
    for(int i = k;i<N;++i)
    {
        sum += c[i];
    }
    return sum>0.0;
}

int main()
{
    scanf("%d%d",&N,&k);
    while(!(N==0&&k==0))
    {
        for(int i = 0;i<N;++i)
        {
            scanf("%lf",&a[i]);
        }
        for(int i = 0;i<N;++i)
        {
            scanf("%lf",&b[i]);
        }
        int tt = 100;
        double l = 0;
        double r = 100;
        double mid;
        while(tt--)//循环一百遍啊一百遍……
        {
            mid = (l+r)/2.0;
            for(int i = 0;i<N;++i)
            {
                c[i] = 100*a[i]-mid*b[i];
            }
            sort(c,c+N);
            if(solve())
                l = mid;
            else
                r = mid;
        }
        int res = l+0.5000001;//四舍五入的方案……
        printf("%d\n",res);
        scanf("%d%d",&N,&k);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值