【问题记录】——求序列子区间最大平均值

这篇博客介绍了一种利用二分法解决序列中长度大于f的子区间平均值最大值的问题。首先假设一个平均值,然后通过构建前缀和数组来检查是否存在满足条件的区间。通过不断调整平均值,最终找到最大平均值。代码示例展示了具体的实现过程。
摘要由CSDN通过智能技术生成

问题描述

给定一个序列求其长度大于f的子区间的平均值的最大值

思路

求平均值可以用二分法来找平均值,先假设一个平均值,让原序列a减去假设平均值生成一个新序列b,b序列中有正有负,将b序列的前缀和存在sum数组中,区间[i,j]的和表示为sum[j]-sum[i],如果存在区间和大于0,说明平均值还可以更大一些。这样求得的平均值稍有误差,可以控制误差的数量级。

实现代码

int a[maxn];      //a数组
double b[maxn];      //a数组减去假设平均值
double sum[maxn];    //b的前缀和
double judgeAve(int n, double mid, int f)
{
    for(int i = 1;i <= n;i++)
    {
        b[i] = a[i] - mid;
        sum[i] = sum[i - 1] + b[i];
    }
    double min_val = 1e10, max_val = -1e10;
    for(int i = f;i <= n;i++)
    {
        if(min_val > sum[i - f])
        {
            min_val = sum[i - f];
        }
        if(max_val < sum[i]-min_val)
        {
            max_val = sum[i]-min_val;
        }
    }
    return max_val;
}
double largestAve(int a[],int n,int f)//a数组,数组长度为n,f子区间长度
{
    double mid;
    double l = 0,r = 1e5, eps = 1e-8;
    while(r - l > eps)
    {
        mid = (r + l) / 2;
        if(judgeAve(n, mid, f) > 0)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    return r;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值