[ABC201F]Insertion Sort
Posted Tan_tan_tann
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ABC201F]Insertion Sort相关的知识,希望对你有一定的参考价值。
[ABC201F]Insertion Sort
题解
我们其实很容易想到最后的方案数一定是通过 1 / 2 1/2 1/2操作将一部分的编号小的人排好序,通过 1 / 3 1/3 1/3操作将一部分编号大的人排好序,中间的人通过不移动或 1 1 1操作排好序。
前面的部分排序与后面的部分排序都是比较好得到的,就是 ∑ i = 1 k min ( a i , b i ) \\sum_{i=1}^{k}\\min(a_{i},b_{i}) ∑i=1kmin(ai,bi)和 ∑ i = k ′ n min ( a i , c i ) \\sum_{i=k'}^{n}\\min(a_{i},c_{i}) ∑i=k′nmin(ai,ci),关键是中间一部分的排序。
我们可以考虑
d
p
dp
dp,令
d
p
l
,
r
dp_{l,r}
dpl,r表示将区间
[
l
,
r
]
[l,r]
[l,r]排好序的方案,很明显有转移方程式,
d
p
l
,
r
=
min
p
o
s
k
⩽
p
o
s
r
d
p
l
,
k
+
∑
j
=
k
+
1
r
−
1
a
j
dp_{l,r}=\\min_{pos_{k}\\leqslant pos_{r}}dp_{l,k}+\\sum_{j=k+1}^{r-1}a_{j}
dpl,r=posk⩽posrmindpl,k+j=k+1∑r−1aj
很明显,即使使用单调栈与前缀和优化后,这个转移还是
O
(
n
2
l
o
g
n
)
O\\left(n^2log\\,n\\right)
O(n2logn),根本不可能过。
我们可以先将上式改一改,有
d
p
l
,
r
=
∑
j
=
1
r
a
j
+
min
p
o
s
k
⩽
p
o
s
r
(
d
p
l
,
k
−
∑
j
=
1
k
a
j
)
dp_{l,r}=\\sum_{j=1}^{r}a_{j}+\\min_{pos_{k}\\leqslant pos_{r}}(dp_{l,k}-\\sum_{j=1}^{k}a_{j})
dpl,r=j=1∑raj+posk⩽posrmin(dpl,k−j=1∑kaj)
这样后面的部分就不与
r
r
r相关了,而对于
r
r
r,它只会选择位置在它左边的
d
p
dp
dp进行转移,于是我们就可以想到维护一棵以
p
o
s
pos
pos为下标建的线段树。
d p dp dp也可以改改,定义 d p i , j dp_{i,j} dpi,j表示枚举了前 i i i个人后末位置在 j j j时的最小花费,将前面与中间两部分合并在一起。
很明显,当我们新增加一个人 i i i时,只有 d p i , p o s i dp_{i,pos_{i}} dpi,posi的值会发生改变,其他的都是直接加上 a i a_{i} ai。
对于
d
p
i
,
p
o
s
i
dp_{i,pos_{i}}
dpi,posi,有转移方程式
d
p
i
,
p
o
s
i
=
min
(
∑
j
=
1
i
−
1
min
(
a
j
,
b
j
)
,
∑
j
=
1
i
a
j
+
min
j
=
1
i
(
d
p
j
,
p
o
s
j
−
∑
k
=
1
j
a
k
)
)
dp_{i,pos_{i}}=\\min(\\sum_{j=1}^{i-1}\\min(a_{j},b_{j}),\\sum_{j=1}^{i}a_{j}+\\min_{j=1}^{i}(dp_{j,pos_{j}}-\\sum_{k=1}^{j}a_{k}))
dpi,posi=min(j=1∑i−1min(aj,bj),j=1∑iaj+j=1mini(dpj,posj−k=1∑jak))
由于我们线段树维护的是 d p j , p o s j − ∑ k = 1 j a k dp_{j,pos_{j}}-\\sum_{k=1}^{j}a_{k} dpj,posj−∑k=1jak,只与 j j j有关,所以线段树是不用修改的,只需要将 d p i , p o s i − ∑ k = 1 i a k dp_{i,pos_{i}}-\\sum_{k=1}^{i}a_{k} dpi,posi−∑k=1ia147. Insertion Sort List
#Leetcode# 147. Insertion Sort List