poj2018(高精度二分+dp)

题意:给你n个数,要你在这n个数里面找到一些连续的数,这些数的数量大于等于m,并且他们的平均值在这n个数里面是最大的.......

思路:先把n个数的最大最小值确定,然后二分枚举平均值,对于每一个连续数,只要他们减去平均值大于0,就调制上限制,不然调整下限制,.......

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double s[100005],sum[100005];
int n,m;
int deal(double ans)
{
    double f=sum[m-1]-(m-1)*ans;
    //if(f>-1e-6)
    //return 1;
    for(int i=m;i<=n;i++)
    {
        f=f+s[i]-ans;
        f=max(f,sum[i]-sum[i-m]-m*ans);//不要前面的数,新开的m个数,与要前面的数比较,去最大值
        if(f>-1e-6)
        return 1;
    }
    return 0;
}
int main()
{
    while(scanf("%d%d",&n,&m)>0)
    {
        double maxn=0,minx=100000000;
        sum[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&s[i]);
            if(maxn<s[i])
            maxn=s[i];
            if(minx>s[i])
            minx=s[i];
            sum[i]=sum[i-1]+s[i];
        }
        //double ans=0;
        while(maxn-minx>=1e-6)
        {
            double mid=(maxn+minx)/2;
            if(deal(mid))
            {
                //ans=mid;
                minx=mid;
            }
            else
            {
                //ans=maxn;
                maxn=mid;
            }

        }
        int y=(maxn*1000);
        printf("%d\n",y);
    }
    return 0;
}

 

 

posted @ 2013-09-11 00:56  紫忆  阅读(1471)  评论(0编辑  收藏  举报