あなたは、...、のシーケンスを与えられたn個の整数は、A1、A2います。
X、A2 - - X、...、 - xは可能な限り小さくある。シーケンスa1の弱さがあるよう実数Xを決定します
配列の弱さは、配列のすべてのセグメント(隣接配列)上悪さの最大値として定義されます。
セグメントの悪さは、セグメントの要素の総和の絶対値として定義されます。
入力
最初の行は、一つの整数N(1≤N≤200 000)、配列の長さを含みます。
2行目は含まれていnは整数A1、A2、...、(|愛|≤10 000)。
出力
A1の最小の可能な弱さを示す出力実数- X、A2 - X、...、X - 。6 -その相対的または絶対誤差が10を超えていない場合はあなたの答えが正しいとみなされます。
例
入力
3
1 2 3
出力
1.000000000000000
入力
4
1つの2 3 4
出力
2.000000000000000
入力
10
1 10 2 9 3 8 4 7 5 6
出力
4.500000000000000
注
、1 -最初のケースでは、xの最適値は、2配列になるようです0、1とmax悪さは、セグメント「-1」又はセグメント「1」で起こります。悪値(答えは)このような場合には1に等しいです。
1.5 - - 0.5、0.5、1.5および最大悪さは、セグメント上で発生する「-1.5 -0.5」又は「0.5~1.5」配列となるように、第2のサンプルについてのXの最適値は2.5です。悪値(答えは)この場合は2に等しいです。
タイトルの意味:
列数A1、A2、A3 ...。あなたは、列の数がA1-X、A2-X、なるように、xの数から選択することができる A3-X···-X。
サブセグメントの列数の絶対最大値。使用可能な列の最小数を探しています。
思考:
と仮定すると、SKの値{maxの- X K}。長さkのサブセグメントのSKを表します。
xの各要素値の列の数の増加に伴って明らかにXで単調に減少する、ますます小さくなります。
次に{マックス|、SKの- X K |}像後の画像は、単峰性明らかに、折り畳み点対称に応じて単調関数です。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const double eps = 4e-12;
const double INF = 0x3f3f3f3f;
const int maxn = 2e5 + 7;
int n;
double a[maxn],b[maxn],c[maxn];
double sum1[maxn],sum2[maxn];
double f(double x)
{
double mx1 = -100000.0,mx2 = -100000.0;
double now1 = 0.0,now2 = 0.0;
for(int i = 1;i <= n;i++)
{
b[i] = a[i] - x;
c[i] = -b[i];
if(now1 < 0.0)now1 = 0.0;
if(now2 < 0.0)now2 = 0.0;
now1 += b[i];now2 += c[i];
mx1 = max(now1,mx1);mx2 = max(mx2,now2);
}
return max(mx1,mx2);
}
double f2(double x)
{
double mx1 = -100000.0,mx2 = -100000.0;
sum1[0] = 0.0;sum2[0] = 0.0;
for(int i = 1;i <= n;i++)
{
b[i] = a[i] - x;
c[i] = -b[i];
sum1[i] = max(sum1[i - 1] + b[i],b[i]);
sum2[i] = max(sum2[i - 1] + c[i],c[i]);
mx1 = max(sum1[i],mx1);mx2 = max(sum2[i],mx2);
}
return max(mx1,mx2);
}
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%lf",&a[i]);
}
double l = -20000.0,r = 20000.0;
double ans = 0.0;
int cnt = 0;
while(r - l > eps)
{
double m1 = l + (r - l) / 3.0,m2 = l + 2.0 * (r - l) / 3.0;
// printf("%.20f %.20f\n",l,r);
if(f(m1) < f(m2))
{
ans = m1;
r = m2;
}
else
{
ans = m2;
l = m1;
}
}
printf("%.6f\n",f(ans));
return 0;
}