Poj2018 Best Cow Fences

Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains 

a certain number of cows, 1 <= ncows <= 2000.
FJ wants to build a fence around a contiguous group of these fields in order to maximize the
average number of cows per field within that block. The block must contain at least F (1 <= F <= N)
fields, where F given as input.

Calculate the fence placement that maximizes the average, given the constraint.

输入N个数,从中取至少F个数,这些数的平均值越大越好!

输入
* Line 1: Two space-separated integers, N and F.
* Lines 2..N+1: Each line contains a single integer, the number of cows in a field.
Line 2 gives the number of cows in field 1,line 3 gives the number in field 2, and so on.
输出
* Line 1: A single integer that is 1000 times the maximal average.Do not perform rounding, just print the integer that is 1000*ncows/nfields.
样例输入
10 6
6
4
2
10
3
8
5
9
4
1
样例输出
6500

 

//先二分平均数,然后将各个元素减去平均数,处理前缀和。
//然后利用前缀和,判断最大子段和是否大于0。
 
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;double b[100001],a[100001],sum[100001];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lf",&a[i]);
    double l=0,r=2000,minn=1e-5;
    while(r-l>minn)
    {
        double mid=(l+r)/2,maxx=1e10,ans=-1e10;//二分平均数
        for(int i=1;i<=n;i++)
            b[i]=a[i]-mid,sum[i]=b[i]+sum[i-1];//将每块地的牛的头数都减去平均数,再求前缀和
        for(int i=m;i<=n;i++)//计算m~n块地的最大字串和
        {
            maxx=min(maxx,sum[i-m]);//在sum[0]~sum[i-m]中选最小值
            ans=max(ans,sum[i]-maxx);//所有sum[i]-maxx中取最大,即最大子段和
        }
        if(ans>=0) l=mid;//如果ans>=0,则说明能够到达平均数,平均数还可以再提高
        else r=mid;//否则说明不能到达,平均数应降低
    }
    printf("%d",(int)(r*1000));//题目要求答案*1000
}

  

posted @ 2020-10-26 16:35  我微笑不代表我快乐  阅读(101)  评论(0编辑  收藏  举报