4518: [Sdoi2016]征途

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

Pine开始了从S地到T地的征途。
从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。
Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。
Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。
帮助Pine求出最小方差是多少。
设方差是v,可以证明,v×m^2是一个整数。为了避免精度误差,输出结果时输出v×m^2。

Input

第一行两个数 n、m。
第二行 n 个数,表示 n 段路的长度

Output

一个数,最小方差乘以 m^2 后的值

Sample Input

5 2
1 2 5 8 6

Sample Output

36

HINT

1≤n≤3000,保证从 S 到 T 的总路程不超过 30000

题解:

推式子的感觉真刺激呀....

我们复习一下方差的定义:数值与平均值之差的平方和的平均值

设s[i]为前缀和,设X0是平均值,则X0=s[n]/m

也就是说,V=((X1-X0)+(X2-X0)+......+(Xm-X0))/m

由于答案是V*m,所以我们不妨把m直接带上.

所以有:

ans=((X1-X0)+(X2-X0)+......+(Xm-X0))*m

   =m*ΣXi+m*X0*m-2*X0*m*ΣXi

   =m*ΣXi+s[n]-2*s[n]

=m*ΣXi-s[n]

这样我们就找到了一个很简洁的表达式

但是如果直接计算这个式子,你会发现推不出来,所以我们转化一下角度,转而计算ΣXi的值.

我们可以维护一个数组f[i][j],表示在第j段路结尾,第i次休息的时候最小的ΣXi,那么答案就是m*f[m][n]-s[n]

那么f[i][j]=min{f[k][j-1]+(s[i]-s[k])}.

分析一下复杂度,Ο(m*n*n),如果是极限数据会变成3000,这样就要t了

所以我们考虑优化,对于可能转移到i的2个位置k1与k2,k1优于k2的条件是什么?(公式恐惧症的同学不要跑啊......)

f[k][j-1]+(s[i]-s[k])<f[k][j-1]+(s[i]-s[k])

f[k][j-1]-f[k][j-1]<(s[i]-s[k])-(s[i]-s[k])

f[k][j-1]-f[k][j-1]<s[i]-2*s[i]*s[k]+s[k]-(s[i]-2*s[i]*s[k]+s[k])

f[k][j-1]-f[k][j-1]<s[k]-s[k]-2*s[i]*s[k]+2*s[i]*s[k]

f[k][j-1]-f[k][j-1]+s[k]-s[k]<2*s[i]*(s[k]-s[k])

(f[k][j-1]-f[k][j-1]+s[k]-s[k])/(s[k]-s[k])<2*s[i]

所以我们用一个单调队列维护就行啦,剩下的维护判断就比较简单了~

代码见下:

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=;
LL len[N],n,m,s[N],f[N][N];
int q[N];
inline int min(int a,int b){return a<b?a:b;}
inline double k(int j,int k1,int k2)
{
double a=(double)(f[j-][k1]-f[j-][k2]+s[k1]*s[k1]-s[k2]*s[k2]);
return a/(double)(s[k1]-s[k2]);
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
scanf("%lld",&len[i]),s[i]=s[i-]+len[i];
for(int j=;j<=n;j++)
f[][j]=s[j]*s[j];
for(int i=,h=,t=;i<=m;i++,h=,t=)
{
memset(q,,sizeof(q));
for(int j=;j<=n;j++)
{
while(h<t&&k(i,q[h+],q[h])<*s[j])h++;
f[i][j]=f[i-][q[h]]+(s[j]-s[q[h]])*(s[j]-s[q[h]]);
while(h<t&&k(i,j,q[t])<k(i,q[t],q[t-]))t--;
q[++t]=j;
}
}
printf("%lld",m*f[m][n]-s[n]*s[n]);
}

BZOJ4815

05-11 22:13