二分法求最大平均值问题

二分法求最大平均值问题

核心思路

找到要求的目标值的上下界,作为二分法的左右边界。进行迭代,其中迭代缩小的原则是:在内部进行此时mid值的判断,如果判定mid值在题目给出的条件中,还有提高的空间,则缩小左边界。如果mid值超出了题目中条件可以满足的范围,则缩小右边界,以此不断缩小,直到左右逼近到差值在一定的精度上。

【例1】切绳子。

题目描述

有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2位后的小数)。

输入输出格式

输入格式:

第一行两个整数N和K ( 0 < N < = 10000 , 0 < K < = 10000 ) (0<N<=10000, 0<K<=10000) 0<N<=100000<K<=10000,接下来N行,描述了每条绳子的长度Li ( 0 < L i < = 100000.00 ) (0<Li<=100000.00) 0<Li<=100000.00

输出格式:

切割后每条绳子的最大长度。

输入输出样例

输入样例#1:

4 11

8.02

7.43

4.57

5.39

输出样例#1:

2.00

(1)编程思路。

先确定初始区间[left,right],显然left=0,right可取单段绳子的最大值,然后使用二分法得到mid,测试mid是大于要求的值还是小于要求的值。

如果mid值可以切出k段绳子,则增大下界,使left=mid;如果mid值切不出k段绳子,则mid取大了,减小上界,使right=mid;.然后最终使left 与right无限逼近答案。

注意:程序中可以使用 while ((right-left)>1e-4)作为循环控制条件。

(2)源程序。
#include <stdio.h>

#include <math.h>

#define MAX_N 10000

double a[MAX_N+1];

int n,k;

int judge(double x)

{

         int num = 0,i;

         for (i = 0; i < n; i++)

                   num += (int)(a[i] / x);

         return num;

}

int main()

{

    int i;

    double left,right,mid,max=0;

         scanf("%d%d",&n,&k);

    for(i=0;i<n;i++)

    {

            scanf("%lf",&a[i]);

            if (max<a[i]) max=a[i];

    }

    left=0, right=max;

    while ((right-left)>1e-4)

    {

        mid=(left+right)/2;

        if(judge(mid)>=k) left=mid;

        else right=mid;

    }

    printf("%.2f\n",floor(right*100)/100);

    return 0;

}

拓展

讲的特别好的Best Cow Fences

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值