Print Article | HDU3507 有一个长度为
n
n
n 的序列
C
C
C 把它分成一些子区间,总的花费为:
∑
每
个
子
区
间
k
(
(
∑
i
在
子
区
间
k
C
i
)
2
+
M
)
\sum_{每个子区间 k} \Big( \Big( \sum_{i在子区间k}C_i \Big)^2+M \Big)
每个子区间k∑((i在子区间k∑Ci)2+M) 求总花费的最小值
1
≤
n
≤
5
×
1
0
5
1\le n\le 5\times10^5
1≤n≤5×105
1
≤
C
i
≤
1
0
3
1\le C_i\le 10^3
1≤Ci≤103
思路
我们直接进行一个
D
N
A
DNA
DNA 的动,设
d
p
[
i
]
dp[i]
dp[i] 表示选完了
1
∼
i
1\sim i
1∼i 的位置,最小的总花费 记录一个前缀和数组
p
r
e
[
x
]
=
∑
i
=
1
x
C
i
pre[x]=\sum_{i=1}^x C_i
pre[x]=∑i=1xCi 转移也很简单:
d
p
[
i
]
=
min
j
=
0
i
−
1
{
d
p
[
j
]
+
(
p
r
e
[
i
]
−
p
r
e
[
j
]
)
2
}
+
M
dp[i]=\min_{j=0}^{i-1}\{ dp[j]+(pre[i]-pre[j])^2 \} + M
dp[i]=j=0mini−1{dp[j]+(pre[i]−pre[j])2}+M 但是这个复杂度很明显为
O
(
n
2
)
\color{red}{O(n^2)}
O(n2) ,我们怎么去优化呢? 根据决策单调性的相关知识,我们可以通过某种方式将其优化!
设
0
≤
k
2
<
k
1
<
i
0\le k_2<k_1<i
0≤k2<k1<i ,假设我们从
k
1
k_1
k1 那边转移到
i
i
i 更优,那么我们有:
d
p
[
k
2
]
+
(
p
r
e
[
i
]
−
p
r
e
[
k
2
]
)
2
<
d
p
[
k
1
]
+
(
p
r
e
[
i
]
−
p
r
e
[
k
1
]
)
2
dp[k_2]+(pre[i]-pre[k_2])^2 < dp[k_1]+(pre[i]-pre[k_1])^2
dp[k2]+(pre[i]−pre[k2])2<dp[k1]+(pre[i]−pre[k1])2
化简得到:
(
d
p
[
k
2
]
−
d
p
[
k
1
]
+
p
r
e
[
k
2
]
2
−
p
r
e
[
k
1
]
2
)
/
(
p
r
e
[
k
2
]
−
p
r
e
[
k
1
]
)
>
2
×
p
r
e
[
i
]
(dp[k_2]-dp[k_1]+pre[k_2]^2-pre[k_1]^2)/(pre[k_2]-pre[k_1])>2\times pre[i]
(dp[k2]−dp[k1]+pre[k2]2−pre[k1]2)/(pre[k2]−pre[k1])>2×pre[i] 我们令
Y
(
x
)
=
d
p
[
x
]
+
p
r
e
[
x
]
2
Y(x)=dp[x]+pre[x]^2
Y(x)=dp[x]+pre[x]2 令
X
(
x
)
=
p
r
e
[
x
]
X(x)=pre[x]
X(x)=pre[x] 那么式子就变成了:
Y
(
k
2
)
−
Y
(
k
1
)
X
(
k
2
)
−
X
(
k
1
)
>
2
×
p
r
e
[
i
]
\frac{Y(k_2)-Y(k_1)}{X(k_2)-X(k_1)}>2\times pre[i]
X(k2)−X(k1)Y(k2)−Y(k1)>2×pre[i]
而右边我们放的是一个常数,假设为
K
(
i
)
K(i)
K(i) ,那式子可以想成:其中两个点之间的斜率大于
K
(
i
)
K(i)
K(i) 因为我们一开始定义
k
1
k_1
k1 更优的话,要求有这个式子 我们可以记录,从这个点
k
1
k_1
k1 出发,到之后的某个
k
2
k_2
k2 ,斜率最小是多少? 如果斜率最小都
>
K
(
i
)
>K(i)
>K(i) 了,自然选这个点是最最优的。 我们可以使用求凸包的方法,快速去维护。 注意到,随着
i
i
i 递增,
p
r
e
[
i
]
pre[i]
pre[i] 也是单递增的,也就是我们的
K
(
i
)
K(i)
K(i) 也是单递增 的,我们就可以用类似单调队列 的写法,达到
O
(
N
)
\color{green}{O(N)}
O(N) 的优秀复杂度
更套路的做法
主要是上面的转移,希望写得更快一点 (???) ,有新的办法去做 考虑式子:
d
p
[
i
]
=
min
j
=
0
i
−
1
{
d
p
[
j
]
+
(
p
r
e
[
i
]
−
p
r
e
[
j
]
)
2
}
+
M
dp[i]=\min_{j=0}^{i-1}\{ dp[j]+(pre[i]-pre[j])^2 \} + M
dp[i]=j=0mini−1{dp[j]+(pre[i]−pre[j])2}+M
我们省略
min
\min
min 函数,拆开来变成:
d
p
[
i
]
=
d
p
[
j
]
+
p
r
e
[
i
]
2
+
p
r
e
[
j
]
2
−
2
p
r
e
[
i
]
p
r
e
[
j
]
+
M
dp[i]=dp[j]+pre[i]^2+pre[j]^2-2pre[i]pre[j]+M
dp[i]=dp[j]+pre[i]2+pre[j]2−2pre[i]pre[j]+M 由于考虑斜率,我们希望写成
y
=
k
x
+
b
y=kx+b
y=kx+b 的形式:
d
p
[
j
]
+
p
r
e
[
j
]
2
=
2
p
r
e
[
i
]
p
r
e
[
j
]
+
(
d
p
[
i
]
−
p
r
e
[
i
]
2
−
M
)
dp[j]+pre[j]^2=2pre[i]pre[j]+(dp[i]-pre[i]^2-M)
dp[j]+pre[j]2=2pre[i]pre[j]+(dp[i]−pre[i]2−M) 这里,只与
j
j
j 有关的函数我们放在
y
y
y 的位置 与
i
,
j
i,j
i,j 都有关的函数我们放在
k
x
kx
kx 的位置,并令
k
k
k 表示只与
i
i
i 有关的内容,令
x
x
x 表示只与
j
j
j 有关的内容 只与
i
i
i 有关的函数我们放在
b
b
b 的位置 然后我们发现,其实就是之前的
Y
(
x
)
=
d
p
[
x
]
+
p
r
e
[
x
]
2
Y(x)=dp[x]+pre[x]^2
Y(x)=dp[x]+pre[x]2 ,
X
(
x
)
=
p
r
e
[
x
]
X(x)=pre[x]
X(x)=pre[x] ,
K
(
x
)
=
2
p
r
e
[
x
]
K(x)=2pre[x]
K(x)=2pre[x]
接下来,我们需要求
d
p
[
i
]
dp[i]
dp[i] 最小,就是希望我们
b
b
b 最小;由于我们的
x
,
k
x,k
x,k 都是单递增的,所以我们构造 下凸包,就可以达到我们的目的