您的位置:首页 > 其它

BZOJ 4518: [Sdoi2016]征途

2018-01-19 20:37 309 查看

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

分析

=====m2×∑i=1m(ai−Sm)2mm2×∑i=1ma2i+(Sm)2−2aiSmmm2×(∑i=1ma2im+∑i=1mS2m3−2∑i=1maiSm2)m2×(∑i=1ma2im+S2m2−2×S2m2)m2×(∑i=1ma2im−S2m2)m×∑i=1ma2i−S2

因为 m 是个常数,S2 是个常数,所以只要最小化

∑i=1ma2i

即可

设 f[j][i] 表示前 i 段路,分成 j 天的最优方案对应上式的值,则有

f[j][i]=mink=1j−1{f[j−1][k]+(s[i]−s[k])2}

直接以这个式子进行划分DP,状态数为 O(nm),时间复杂度为 O(nm2),预计得分 60 分。

尝试进行优化。首先,二维的状态存储,显然第一维是可以滚动的,设 g(i)=f[j−1][i]。考虑 k 的两个取值 k=a 和 k=b(a>b),若 a 比 b 优,则有

g(a)+(si−sa)2g(a)+s2i+s2a−2sisag(a)+s2a−2sisag(a)−g(b)+s2a−s2bg(a)−g(b)+s2a−s2b(g(a)+s2a)−(g(b)+s2b)sa−sb<g(b)+(si−sb)2<g(b)+s2i+s2b−2sisb<g(b)+s2b−2sisb<2sisa−2sisb<2si(sa−sb)<2si

然后就没了

代码

#include <bits/stdc++.h>

#define sqr(x) (1ll * (x) * (x))

int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
}

const int N = 3050;

int n,m;
int a
,s
;
long long f
,g
;

double slope(int a,int b)
{
return (double)(g[a] - g[b] + sqr(s[a]) - sqr(s[b])) / (double)(s[a] - s[b]);
}

int main()
{
int n = read(), m = read();
for (int i = 1; i <= n; i++)
a[i] = read();
for (int i = 1; i <= n; i++)
s[i] = s[i - 1] + a[i];
for (int i = 1; i <= n; i++)
f[i] = INT_MAX;
for (int j = 1; j <= m; j++)
{
memcpy(g, f, sizeof(f));
memset(f, 0, sizeof(f));
static int q
;
int l = 0, r = -1;
q[++r] = 0;
for (int i = 1; i <= n; i++)
{
while (l < r && slope(q[l + 1], q[l]) < 2 * s[i])
l++;
int t = q[l];
f[i] = g[t] + sqr(s[i] - s[t]);
while (l < r && slope(q[r], q[r - 1]) > slope(q[r], i))
r--;
q[++r] = i;
}
}
printf("%d\n",(int)(f
* m - sqr(s
)));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: