Poj 2976 Dropping tests(二分)

本文提供了一种解决POJ 2976问题的有效算法。通过二分查找确定最优比例r,并利用贪心策略计算最大价值。具体步骤包括设定初始边界值,迭代更新r值直到满足精度要求,最终输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:http://poj.org/problem?id=2976

思路:max{sigma(a[i])/sigma(b[i])}。设r=sigma(a[i]*x[i])/sigma(b[i]*x[i])(x[i]=0,1)。则sigma(a[i]*x[i])-r*sigma(b[i]*x[i])=0,而sigma(a[i]*x[i])-max(r)*(sigma(b[i]*x[i]))<=0,当且仅当max(r)=sigma(a[i]*x[i])/sigma(b[i]*x[i])时取等号。则二分r,求f(r)=sigma(a[i]*x[i])-r*sigma(b[i]*x[i])的最大值,若最大值为0,则当前r即为答案(对于r=max(r)时,所有值均不大于0,最大值为0)。若f(r)>0,则l=mid,此时r偏小;若f(r)<0,则r=mid,此时r偏大。求最大值:设tmp[i]=a[i]-r*b[i],将tmp从小到大排序,第k+1到第n个值的和即为当前r下的最大值。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e3+50;
const double eps=1e-7;
int n,k;
double tmp[maxn];
int a[maxn],b[maxn];
int check(double x)
{
    for(int i=1;i<=n;i++)
        tmp[i]=a[i]-x*b[i];
    sort(tmp+1,tmp+n+1);
    double sum=0.0;
    for(int i=k+1;i<=n;i++) sum+=tmp[i];
    return sum>=0;
}
int main()
{
    while(scanf("%d%d",&n,&k)!=EOF&&n)
    {
        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.0,r=101.0,mid;
        while(r-l>=eps)
        {
            mid=(l+r)/2;
            if(check(mid)) l=mid;
            else r=mid;
        }
        printf("%d\n",(int)(l*100+0.5));
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值