题目描述
给定一个长度为n的序列,求其中平均值最大长度不少于L的序列
将平均值*1000输出
样例
Sample Input
10 6
6
4
2
10
3
8
5
9
4
1
Sample Output
6500
思路
二分答案,存在一个数mid使序列上所有的数减去mid, 此时将原问题转换成了求一个序列长度不少于L,他的和不少于0,此时我们用sum数组存下减去mid后序列的前缀和,即是求在下标L以后的点x,sum[x]-min(sum[1~x-L]),
就是sum[x] 减去 下标1到x-L的的前缀和里面最小的一个数,就是满足条件的最大解,如果这个值大于0,就是往大于mid的一边扩展。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 100010;
const double eps = 1e-8;
double a[N], d[N], sum[N];
int n, L;
int main()
{
scanf("%d%d", &n, &L);
for (int i = 1; i <= n; i++)
scanf("%lf", a + i);
double l = -1e6;
double r = 1e6;
while (r - l > eps)
{
double mid = (r + l) / 2;
for (int i = 1; i <= n; i++)
d[i] = a[i] - mid;
for (int i = 1; i <= n; i++)
sum[i] = d[i] + sum[i - 1];
double ans = -1e10;
double min_val = 1e10;
for (int i = L; i <= n; i++)
{
min_val = min(min_val, sum[i - L]);
ans = max(ans, sum[i] - min_val);
}
if (ans >= 0)
l = mid;
else
r = mid;
}
int res = int(r * 1000);
printf("%d\n", res);
return 0;
}