题目大意: 数轴上有 n n n 个点,给出他们的坐标 s i s_i si,现在要选一些点建邮局,每个点的代价是离他最近的邮局的距离,找到一种方案使所有点总代价最小。
题解
先考虑
40
40
40 分的暴力
O
(
n
3
)
O(n^3)
O(n3)
d
p
dp
dp,设
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示前
i
i
i 个点放
j
j
j 个邮局的最小代价,那么有:
f
[
i
]
[
j
]
=
min
k
=
1
j
{
f
[
k
]
[
j
−
1
]
+
w
(
k
+
1
,
i
)
}
f[i][j]=\min_{k=1}^j\{f[k][j-1]+w(k+1,i)\}
f[i][j]=k=1minj{f[k][j−1]+w(k+1,i)}
其中, w ( k + 1 , i ) w(k+1,i) w(k+1,i) 表示在 k + 1 k+1 k+1 到 i i i 之间放一个邮局的最小代价,显然, w w w 满足 w ( i , i ) = 0 w(i,i)=0 w(i,i)=0。
显然求 w ( a , b ) w(a,b) w(a,b) 就是找到 [ a , b ] [a,b] [a,b] 这一段的中位数(如果有偶数个数,那么中间的两个数其实都是可以选的),然后求出这一段的所有点到中位数的距离之和,这个预处理一下前缀和就好。(如果不明白建议恶补入门贪心qwq)
诶,这个方程长的眉清目秀,莫不是可以用四边形不等式来优化一波?
接下来就是走流程了,一步一步证明下去即可。(如果发现下面有什么跃迁式证明,你可能是没看上面那个链接,不过学过四边形不等式的应该都看得懂qwq)
first
首先证明 w w w 满足四边形不等式,根据推论,也就是要证明:对于任意 a < c a<c a<c,都有 w ( a , c ) + w ( a + 1 , c + 1 ) ≤ w ( a + 1 , c ) + w ( a , c + 1 ) w(a,c)+w(a+1,c+1)\leq w(a+1,c)+w(a,c+1) w(a,c)+w(a+1,c+1)≤w(a+1,c)+w(a,c+1)。
证明:
因为 w ( a + 1 , c + 1 ) w(a+1,c+1) w(a+1,c+1) 和 w ( a , c + 1 ) w(a,c+1) w(a,c+1) 可以取到同样的中位数 m i d 1 mid_1 mid1,所以 w ( a , c + 1 ) w(a,c+1) w(a,c+1) 比 w ( a + 1 , c + 1 ) w(a+1,c+1) w(a+1,c+1) 大 ( s m i d 1 − s a ) (s_{mid_1}-s_a) (smid1−sa)。
同样的, w ( a , c ) w(a,c) w(a,c) 比 w ( a + 1 , c ) w(a+1,c) w(a+1,c) 大 ( s m i d 2 − s a ) (s_{mid_2}-s_a) (smid2−sa)。
于是就有:
w
(
a
,
c
)
+
w
(
a
+
1
,
c
+
1
)
−
(
w
(
a
+
1
,
c
)
+
w
(
a
,
c
+
1
)
)
=
s
m
i
d
2
−
s
a
−
(
s
m
i
d
1
−
s
a
)
=
s
m
i
d
2
−
s
m
i
d
1
w(a,c)+w(a+1,c+1)-(w(a+1,c)+w(a,c+1))=\\ s_{mid_2}-s_a-(s_{mid_1}-s_a)=s_{mid_2}-s_{mid_1}
w(a,c)+w(a+1,c+1)−(w(a+1,c)+w(a,c+1))=smid2−sa−(smid1−sa)=smid2−smid1
由于
m
i
d
2
<
m
i
d
1
mid_2<mid_1
mid2<mid1,所以
s
m
i
d
2
≤
s
m
i
d
1
s_{mid_2}\leq s_{mid_1}
smid2≤smid1,即
s
m
i
d
2
−
s
m
i
d
1
≤
0
s_{mid_2}-s_{mid_1}\leq 0
smid2−smid1≤0,于是得到:
w
(
a
,
c
)
+
w
(
a
+
1
,
c
+
1
)
−
(
w
(
a
+
1
,
c
)
+
w
(
a
,
c
+
1
)
)
≤
0
w
(
a
,
c
)
+
w
(
a
+
1
,
c
+
1
)
≤
w
(
a
+
1
,
c
)
+
w
(
a
,
c
+
1
)
w(a,c)+w(a+1,c+1)-(w(a+1,c)+w(a,c+1))\leq 0\\ w(a,c)+w(a+1,c+1)\leq w(a+1,c)+w(a,c+1)
w(a,c)+w(a+1,c+1)−(w(a+1,c)+w(a,c+1))≤0w(a,c)+w(a+1,c+1)≤w(a+1,c)+w(a,c+1)
证毕。
second
接下来要证明的是对于任意 a ≤ b ≤ c ≤ d a\leq b\leq c\leq d a≤b≤c≤d,都有 w ( a , d ) ≥ w ( b , c ) w(a,d)\geq w(b,c) w(a,d)≥w(b,c)。
a a a 到 d d d 的数字肯定比 b b b 到 c c c 数字多,那么到中位数的距离之和显然会变大……
third
当我写完的时候我发现自己搞错了一些定义,只好从头再来……
接下来证明 f f f 满足四边形不等式,即证明对于任意 a < c a<c a<c,都有 f [ a ] [ c ] + f [ a + 1 ] [ c + 1 ] ≤ f [ a + 1 ] [ c ] + f [ a ] [ c + 1 ] f[a][c]+f[a+1][c+1]\leq f[a+1][c]+f[a][c+1] f[a][c]+f[a+1][c+1]≤f[a+1][c]+f[a][c+1]。
先考虑
c
=
1
c=1
c=1 的情况,此时有:
f
[
a
]
[
c
]
+
f
[
a
+
1
]
[
c
+
1
]
=
f
[
a
]
[
1
]
+
f
[
a
+
1
]
[
2
]
=
f
[
a
+
1
]
[
2
]
+
w
(
1
,
a
)
f
[
a
+
1
]
[
c
]
+
f
[
a
]
[
c
+
1
]
=
f
[
a
+
1
]
[
1
]
+
f
[
a
]
[
2
]
=
f
[
a
]
[
2
]
+
w
(
1
,
a
+
1
)
f[a][c]+f[a+1][c+1]=f[a][1]+f[a+1][2]=f[a+1][2]+w(1,a)\\ f[a+1][c]+f[a][c+1]=f[a+1][1]+f[a][2]=f[a][2]+w(1,a+1)
f[a][c]+f[a+1][c+1]=f[a][1]+f[a+1][2]=f[a+1][2]+w(1,a)f[a+1][c]+f[a][c+1]=f[a+1][1]+f[a][2]=f[a][2]+w(1,a+1)
相减得到:
f
[
a
+
1
]
[
2
]
−
f
[
a
]
[
2
]
+
w
(
1
,
a
)
−
w
(
1
,
a
+
1
)
f[a+1][2]-f[a][2]+w(1,a)-w(1,a+1)
f[a+1][2]−f[a][2]+w(1,a)−w(1,a+1)
设 f [ a ] [ 2 ] f[a][2] f[a][2] 的最优决策为 p p p,那么有 f [ a ] [ 2 ] = w ( 1 , p ) + w ( p + 1 , a ) f[a][2]=w(1,p)+w(p+1,a) f[a][2]=w(1,p)+w(p+1,a)。
这个决策对于 f [ a + 1 ] [ 2 ] f[a+1][2] f[a+1][2] 来说不一定最优,所以 f [ a + 1 ] [ 2 ] ≤ w ( 1 , p ) + w ( p + 1 , a + 1 ) f[a+1][2]\leq w(1,p)+w(p+1,a+1) f[a+1][2]≤w(1,p)+w(p+1,a+1)
将这两个柿子代入上面的柿子得到:
f
[
a
+
1
]
[
2
]
−
f
[
a
]
[
2
]
+
w
(
1
,
a
)
−
w
(
1
,
a
+
1
)
≤
w
(
1
,
p
)
+
w
(
p
+
1
,
a
+
1
)
−
w
(
1
,
p
)
−
w
(
p
+
1
,
a
)
+
w
(
1
,
a
)
−
w
(
1
,
a
+
1
)
=
w
(
p
+
1
,
a
+
1
)
−
w
(
p
+
1
,
a
)
+
w
(
1
,
a
)
−
w
(
1
,
a
+
1
)
f[a+1][2]-f[a][2]+w(1,a)-w(1,a+1)\leq\\ w(1,p)+w(p+1,a+1)-w(1,p)-w(p+1,a)+w(1,a)-w(1,a+1)=\\ w(p+1,a+1)-w(p+1,a)+w(1,a)-w(1,a+1)
f[a+1][2]−f[a][2]+w(1,a)−w(1,a+1)≤w(1,p)+w(p+1,a+1)−w(1,p)−w(p+1,a)+w(1,a)−w(1,a+1)=w(p+1,a+1)−w(p+1,a)+w(1,a)−w(1,a+1)
因为
w
w
w 满足四边形不等式,所以有:
w
(
1
,
a
)
+
w
(
p
+
1
,
a
+
1
)
≤
w
(
1
,
a
+
1
)
+
w
(
p
+
1
,
a
)
w
(
1
,
a
)
+
w
(
p
+
1
,
a
+
1
)
−
w
(
1
,
a
+
1
)
−
w
(
p
+
1
,
a
)
≤
0
w(1,a)+w(p+1,a+1)\leq w(1,a+1)+w(p+1,a)\\ w(1,a)+w(p+1,a+1)-w(1,a+1)-w(p+1,a)\leq 0
w(1,a)+w(p+1,a+1)≤w(1,a+1)+w(p+1,a)w(1,a)+w(p+1,a+1)−w(1,a+1)−w(p+1,a)≤0
代入上面的柿子,最终得到:
f
[
a
+
1
]
[
2
]
−
f
[
a
]
[
2
]
+
w
(
1
,
a
)
−
w
(
1
,
a
+
1
)
≤
0
f
[
a
+
1
]
[
2
]
+
w
(
1
,
a
)
≤
f
[
a
]
[
2
]
+
w
(
1
,
a
+
1
)
f[a+1][2]-f[a][2]+w(1,a)-w(1,a+1)\leq 0\\ f[a+1][2]+w(1,a)\leq f[a][2]+w(1,a+1)
f[a+1][2]−f[a][2]+w(1,a)−w(1,a+1)≤0f[a+1][2]+w(1,a)≤f[a][2]+w(1,a+1)
即 f [ a ] [ c ] + f [ a + 1 ] [ c + 1 ] ≤ f [ a + 1 ] [ c ] + f [ a ] [ c + 1 ] f[a][c]+f[a+1][c+1]\leq f[a+1][c]+f[a][c+1] f[a][c]+f[a+1][c+1]≤f[a+1][c]+f[a][c+1]。
接下来考虑 ∀ c < a \forall c<a ∀c<a 的情况,假设此时 c = k c=k c=k,以及 c < k c<k c<k 的情况已经证明完了。
设
f
[
a
+
1
]
[
c
]
f[a+1][c]
f[a+1][c] 和
f
[
a
]
[
c
+
1
]
f[a][c+1]
f[a][c+1] 的最优决策点分别为
x
,
y
x,y
x,y,那么有:
f
[
a
+
1
]
[
c
]
=
f
[
x
]
[
c
−
1
]
+
w
(
x
+
1
,
a
+
1
)
f
[
a
]
[
c
+
1
]
=
f
[
y
]
[
c
]
+
w
(
y
+
1
,
a
)
f[a+1][c]=f[x][c-1]+w(x+1,a+1)\\ f[a][c+1]=f[y][c]+w(y+1,a)
f[a+1][c]=f[x][c−1]+w(x+1,a+1)f[a][c+1]=f[y][c]+w(y+1,a)
这两个决策点对于 f [ a ] [ c ] f[a][c] f[a][c] 和 f [ a + 1 ] [ c + 1 ] f[a+1][c+1] f[a+1][c+1] 不一定最优,下面分类讨论:
当
x
≤
y
x\leq y
x≤y 时,有:
f
[
a
]
[
c
]
≤
f
[
x
]
[
c
−
1
]
+
w
(
x
+
1
,
a
)
f
[
a
+
1
]
[
c
+
1
]
≤
f
[
y
]
[
c
]
+
w
(
y
+
1
,
a
+
1
)
f[a][c]\leq f[x][c-1]+w(x+1,a)\\ f[a+1][c+1]\leq f[y][c]+w(y+1,a+1)
f[a][c]≤f[x][c−1]+w(x+1,a)f[a+1][c+1]≤f[y][c]+w(y+1,a+1)
综合一下上面的柿子,可以得到:
f
[
a
+
1
]
[
c
]
+
f
[
a
]
[
c
+
1
]
−
f
[
a
]
[
c
]
−
f
[
a
+
1
]
[
c
+
1
]
(
1
)
≥
w
(
x
+
1
,
a
+
1
)
+
w
(
y
+
1
,
a
)
−
w
(
x
+
1
,
a
)
−
w
(
y
+
1
,
a
+
1
)
f[a+1][c]+f[a][c+1]-f[a][c]-f[a+1][c+1]~~(1) \geq\\ w(x+1,a+1)+w(y+1,a)-w(x+1,a)-w(y+1,a+1)
f[a+1][c]+f[a][c+1]−f[a][c]−f[a+1][c+1] (1)≥w(x+1,a+1)+w(y+1,a)−w(x+1,a)−w(y+1,a+1)
因为
w
w
w 满足四边形不等式,所以有:
w
(
x
+
1
,
a
+
1
)
+
w
(
y
+
1
,
a
)
≥
w
(
x
+
1
,
a
)
+
w
(
y
+
1
,
a
+
1
)
w(x+1,a+1)+w(y+1,a)\geq w(x+1,a)+w(y+1,a+1)
w(x+1,a+1)+w(y+1,a)≥w(x+1,a)+w(y+1,a+1)
于是得到: ( 1 ) ≥ 0 (1)\geq 0 (1)≥0,即 f [ a ] [ c ] + f [ a + 1 ] [ c + 1 ] ≤ f [ a + 1 ] [ c ] + f [ a ] [ c + 1 ] f[a][c]+f[a+1][c+1]\leq f[a+1][c]+f[a][c+1] f[a][c]+f[a+1][c+1]≤f[a+1][c]+f[a][c+1]。
当
x
>
y
x>y
x>y 时,
x
x
x 可能等于
a
a
a,而
a
a
a 不能是
f
[
a
]
[
c
]
f[a][c]
f[a][c] 的决策点,所以这里将
x
x
x 代入给
f
[
a
+
1
]
[
c
+
1
]
f[a+1][c+1]
f[a+1][c+1]:
f
[
a
]
[
c
]
≤
f
[
y
]
[
c
−
1
]
+
w
(
y
+
1
,
a
)
f
[
a
+
1
]
[
c
+
1
]
≤
f
[
x
]
[
c
]
+
w
(
x
+
1
,
a
+
1
)
f[a][c]\leq f[y][c-1]+w(y+1,a)\\ f[a+1][c+1]\leq f[x][c]+w(x+1,a+1)
f[a][c]≤f[y][c−1]+w(y+1,a)f[a+1][c+1]≤f[x][c]+w(x+1,a+1)
综合一下上面的柿子,可以得到:
f
[
a
+
1
]
[
c
]
+
f
[
a
]
[
c
+
1
]
−
f
[
a
]
[
c
]
−
f
[
a
+
1
]
[
c
+
1
]
(
2
)
≥
f
[
x
]
[
c
−
1
]
+
f
[
y
]
[
c
]
−
f
[
y
]
[
c
−
1
]
−
f
[
x
]
[
c
]
f[a+1][c]+f[a][c+1] -f[a][c]-f[a+1][c+1]~~(2) \geq\\ f[x][c-1]+f[y][c]-f[y][c-1]-f[x][c]
f[a+1][c]+f[a][c+1]−f[a][c]−f[a+1][c+1] (2)≥f[x][c−1]+f[y][c]−f[y][c−1]−f[x][c]
根据假设,可以得到:
f
[
x
]
[
c
−
1
]
+
f
[
y
]
[
c
]
≥
f
[
y
]
[
c
−
1
]
+
f
[
x
]
[
c
]
f
[
x
]
[
c
−
1
]
+
f
[
y
]
[
c
]
−
f
[
y
]
[
c
−
1
]
−
f
[
x
]
[
c
]
≥
0
f[x][c-1]+f[y][c]\geq f[y][c-1]+f[x][c]\\ f[x][c-1]+f[y][c]-f[y][c-1]-f[x][c]\geq 0
f[x][c−1]+f[y][c]≥f[y][c−1]+f[x][c]f[x][c−1]+f[y][c]−f[y][c−1]−f[x][c]≥0
于是得到: ( 2 ) ≥ 0 (2)\geq 0 (2)≥0,即 f [ a ] [ c ] + f [ a + 1 ] [ c + 1 ] ≤ f [ a + 1 ] [ c ] + f [ a ] [ c + 1 ] f[a][c]+f[a+1][c+1]\leq f[a+1][c]+f[a][c+1] f[a][c]+f[a+1][c+1]≤f[a+1][c]+f[a][c+1]。
forth
接下来要证明的就是最优决策点的优化了: p ( i , j − 1 ) ≤ p ( i , j ) ≤ p ( i + 1 , j ) p(i,j-1)\leq p(i,j)\leq p(i+1,j) p(i,j−1)≤p(i,j)≤p(i+1,j)。
设 p = p ( i , j ) p=p(i,j) p=p(i,j), k k k 满足 i ≤ k < p i\leq k<p i≤k<p。
假设
f
[
i
+
1
]
[
j
]
f[i+1][j]
f[i+1][j] 以
p
,
k
p,k
p,k 作为决策点,那么就有:
k
:
f
[
i
+
1
]
[
j
]
=
f
[
k
]
[
j
−
1
]
+
w
(
k
+
1
,
i
+
1
)
p
:
f
[
i
+
1
]
[
j
]
=
f
[
p
]
[
j
−
1
]
+
w
(
p
+
1
,
i
+
1
)
k:~f[i+1][j]=f[k][j-1]+w(k+1,i+1)\\ p:~f[i+1][j]=f[p][j-1]+w(p+1,i+1)\\
k: f[i+1][j]=f[k][j−1]+w(k+1,i+1)p: f[i+1][j]=f[p][j−1]+w(p+1,i+1)
两式相减得到:
f
[
k
]
[
j
−
1
]
−
f
[
p
]
[
j
−
1
]
+
w
(
k
+
1
,
i
+
1
)
−
w
(
p
+
1
,
i
+
1
)
(
1
)
f[k][j-1]-f[p][j-1]+w(k+1,i+1)-w(p+1,i+1)~~(1)
f[k][j−1]−f[p][j−1]+w(k+1,i+1)−w(p+1,i+1) (1)
假设
f
[
i
]
[
j
]
f[i][j]
f[i][j] 以
p
,
k
p,k
p,k 作为决策点,则有:
k
:
f
[
i
]
[
j
]
=
f
[
k
]
[
j
−
1
]
+
w
(
k
+
1
,
i
)
p
:
f
[
i
]
[
j
]
=
f
[
p
]
[
j
−
1
]
+
w
(
p
+
1
,
i
)
k:~f[i][j]=f[k][j-1]+w(k+1,i)\\ p:~f[i][j]=f[p][j-1]+w(p+1,i)
k: f[i][j]=f[k][j−1]+w(k+1,i)p: f[i][j]=f[p][j−1]+w(p+1,i)
由于
p
p
p 是
f
[
i
]
[
j
]
f[i][j]
f[i][j] 的最优决策点,所以两式相减得到:
f
[
k
]
[
j
−
1
]
−
f
[
p
]
[
j
−
1
]
+
w
(
k
+
1
,
i
)
−
w
(
p
+
1
,
i
)
≥
0
(
2
)
f[k][j-1]-f[p][j-1]+w(k+1,i)-w(p+1,i)\geq 0~~(2)
f[k][j−1]−f[p][j−1]+w(k+1,i)−w(p+1,i)≥0 (2)
因为
w
w
w 满足四边形不等式,所以有:
w
(
p
+
1
,
i
+
1
)
+
w
(
k
+
1
,
i
)
≤
w
(
k
+
1
,
i
+
1
)
+
w
(
p
+
1
,
i
)
w
(
k
+
1
,
i
+
1
)
−
w
(
p
+
1
,
i
+
1
)
≥
w
(
k
+
1
,
i
)
−
w
(
p
+
1
,
i
)
w(p+1,i+1)+w(k+1,i)\leq w(k+1,i+1)+w(p+1,i)\\ w(k+1,i+1)-w(p+1,i+1)\geq w(k+1,i)-w(p+1,i)
w(p+1,i+1)+w(k+1,i)≤w(k+1,i+1)+w(p+1,i)w(k+1,i+1)−w(p+1,i+1)≥w(k+1,i)−w(p+1,i)
将这个柿子和
(
2
)
(2)
(2) 式代入
(
1
)
(1)
(1) 式,得到:
f
[
k
]
[
j
−
1
]
−
f
[
p
]
[
j
−
1
]
+
w
(
k
+
1
,
i
+
1
)
−
w
(
p
+
1
,
i
+
1
)
≥
f
[
k
]
[
j
−
1
]
−
f
[
p
]
[
j
−
1
]
+
w
(
k
+
1
,
i
+
1
)
−
w
(
p
+
1
,
i
+
1
)
≥
0
f[k][j-1]-f[p][j-1]+w(k+1,i+1)-w(p+1,i+1)\geq \\ f[k][j-1]-f[p][j-1]+w(k+1,i+1)-w(p+1,i+1)\geq 0
f[k][j−1]−f[p][j−1]+w(k+1,i+1)−w(p+1,i+1)≥f[k][j−1]−f[p][j−1]+w(k+1,i+1)−w(p+1,i+1)≥0
即 ( 1 ) ≥ 0 (1)\geq 0 (1)≥0,所以对于 f [ i + 1 ] [ j ] f[i+1][j] f[i+1][j], p p p 一定是比 k k k 优的,所以它的决策点一定不可能小于 p p p,即 p ( i , j ) ≤ p ( i + 1 , j ) p(i,j)\leq p(i+1,j) p(i,j)≤p(i+1,j)。
同理,可以得到 p ( i , j − 1 ) ≤ p ( i , j ) p(i,j-1)\leq p(i,j) p(i,j−1)≤p(i,j)。
last
然后用最后的结论优化 d p dp dp 就好了。
代码如下:
#include <cstdio>
#include <cstring>
#define maxn 3010
int n,m,a[maxn];
int sum[maxn],f[maxn][310],p[maxn][maxn];
int w(int x,int y)
{
int mid=x+y>>1;
return sum[y]-sum[mid]-(y-mid)*a[mid]+(mid-x)*a[mid]-(sum[mid-1]-sum[x-1]);
}
int main()
{
scanf("%d %d",&n,&m);
memset(f,63,sizeof(f));
for(int i=1;i<=n;i++)scanf("%d",&a[i]),
sum[i]=sum[i-1]+a[i],f[i][1]=w(1,i),p[i][1]=1;
for(int j=2;j<=m;j++)
{
p[n+1][j]=n;
for(int i=n;i>=1;i--)
for(int k=p[i][j-1];k<=p[i+1][j];k++)
if(f[k][j-1]+w(k+1,i)<f[i][j])f[i][j]=f[k][j-1]+w(k+1,i),p[i][j]=k;
}
printf("%d",f[n][m]);
}
这题的另外一个做法在这里。