标签:ace turn map algo i++ http problem using style
把一个长度为N的序列取出一段长度不小于F的子段,求平均值最大的子段的平均值。
答案似乎不容易看出单调性。。。
换个思路, 一段序列减去平均值后得到的序列, 序列和一定为0.
如果减去的值小于平均值, 则序列和为正, 反之为负。
可以二分一个值, 然后减去这个值, 如果序列中长度不小于F的最大子段和为正, 说明平均值可以再大一些。。
单调性就可以看出来了: 二分值越大, 序列所有数减去二分值后得到的最大子段段和就越小。
关键便是快速判断最大子段和。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<vector> #include<set> #include<cmath> using namespace std; const int mx = 1e5 + 5; const int inf = 1e9; inline void fre(){ freopen("1.txt", "w", stdout); } int n, L; double a[mx], sum[mx]; inline bool check(double mid){ sum[0] = 0; double x; for(int i = 1; i <= n; i++) x = a[i] - mid, sum[i] = sum[i-1] + x; double minn = inf, res = -inf; for(int i = L; i <= n; i++){ minn = min(minn, sum[i-L]); res = max(res, sum[i] - minn); } if(res >= 0) return 1; return 0; } int main(){ //fre(); cin >> n >> L; double l = inf, r = 0; for(int i = 1; i <= n; i++) scanf("%lf", &a[i]), l = min(l, a[i]), r = max(r, a[i]); while(r - l > 0.000001){ double mid = (l+r)/2; if(check(mid)) { l = mid;} else r = mid; } printf("%d\n", (int)(r*1000)); return 0; }
标签:ace turn map algo i++ http problem using style
原文地址:https://www.cnblogs.com/Maktub-blog/p/10995044.html