P8879 『STA - R1』Crossnews
Solution
我们考虑如何得到最优的
对式子进行简单的变形:
后面那部分是定值,我们只需要最小化前面那部分即可。
令
先从简单情况出发。当
建立一个平面直角坐标系。注意到
由于
到此,我们解决了
总结上面的做法,现在我们需要将
Code
#include<cstdio>
#define N 1000005
#define db double
using namespace std;
int n,cnt;
db ans,a[N];
struct node
{
int len;
db val;
node (int l=0,db v=0) {len=l;val=v;}
}q[N];
node merge(node x,node y) {return node(x.len+y.len,(x.val*x.len+y.val*y.len)/(x.len+y.len));}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%lf",&a[i]);
a[i]/=2;
}
for (int i=1;i<=n;++i)
{
q[++cnt]=node(1,a[i]);
while (cnt>1&&q[cnt].val<q[cnt-1].val)
q[cnt-1]=merge(q[cnt],q[cnt-1]),cnt--;
}
for (int i=1,j=1;i<=cnt;++i)
while (q[i].len--)
{
ans+=q[i].val*(q[i].val-a[j]*2);
j++;
}
printf("%.7lf\n",ans);
return 0;
}