Part.0 前置知识
- 简单的 DP 方法;
简单的数学推理能力。
Part.1 四边形不等式
高能数学公式警告
Part.1/1 四边形不等式的概念
四边形不等式优化主要应用于区间 DP 的优化。一般来讲,四边形不等式可以用来优化形如下面的转移方式的 DP:
f ( l , r ) = min k = l r − 1 { f ( l , k ) + f ( k + 1 , r ) } + w ( l , r ) f(l, r) = \min\limits_{k = l}^{r - 1}\{f(l, k) + f(k + 1, r)\} + w(l, r) f(l,r)=k=lminr−1{f(l,k)+f(k+1,r)}+w(l,r)
其中, w ( l , r ) w(l, r) w(l,r) 表示选择区间 [ l , r ] [l, r] [l,r] 的代价。
这样如果直接转移的话复杂度会达到 O ( N 3 ) O(N^3) O(N3) ,然而当 w ( l , r ) w(l, r) w(l,r) 满足如下性质后,复杂度就会优化到 O ( N 2 ) O(N^2) O(N2):
- 区间包含单调性: 对于任意的 l ≤ l ′ ≤ r ′ ≤ r l \le l' \le r' \le r l≤l′≤r′≤r,均有 w ( l ′ , r ′ ) ≤ w ( l , r ) w(l', r') \le w(l, r) w(l′,r′)≤w(l,r) 成立,则称 w w w 有区间包含单调性。
- 四边形不等式: 对于任意的 l 1 ≤ l 2 ≤ r 1 ≤ r 2 l_1 \le l_2 \le r_1 \le r_2 l1≤l2≤r1≤r2,均有 w ( l 1 , r 1 ) + w ( l 2 , r 2 ) ≤ w ( l 1 , r 2 ) + w ( l 2 , r 1 ) w(l_1, r_1) + w(l_2, r_2) \le w(l_1, r_2) + w(l_2, r_1) w(l1,r1)+w(l2,r2)≤w(l1,r2)+w(l2,r1) 成立,则称函数 w w w 满足四边形不等式。特别地,当等号永远成立时,我们称函数 w w w 满足四边形恒等式。
Part.1/2 证明 f ( l , r ) f(l, r) f(l,r) 满足四边形不等式
引理: 若 w w w 同时满足区间包含单调性和四边形不等式,那么 f f f 也满足四边形不等式。
证明: 采用数学归纳法进行证明。我们对区间长度进行归纳。
取 l 1 ≤ l 2 ≤ r 1 ≤ r 2 l_1 \le l_2 \le r_1 \le r_2 l1≤l2≤r1≤r2,记 u u u 为 f ( l 1 , r 2 ) f(l_1, r_2) f(l1,r2) 的最优决策点, v v v 为 f ( l 2 , r 1 ) f(l_2, r_1) f(l2,r1) 的最优决策点。
则分成两种情况讨论:
情况(1): u ≤ v u \le v u≤v。显然有 l 1 ≤ u < r 1 , l 2 ≤ v < r 2 l_1\le u < r_1, l_2 \le v < r_2 l1≤u<r1,l2≤v<r2。
得到不等式组:
{ f ( l 1 , r 1 ) ≤ f ( l 1 , u ) + f ( u + 1 , r 1 ) + w ( l 1 , r 1 ) f ( l 2 , r 2 ) ≤ f ( l 2 , v ) + f ( v + 1 , r 2 ) + w ( l 2 , r 2 ) \begin{cases} f(l_1, r_1) \le f(l_1, u) + f(u + 1, r_1) + w(l_1, r_1) \\ f(l_2, r_2) \le f(l_2, v) + f(v + 1, r_2) + w(l_2, r_2) \end{cases} {f(l1,r1)≤f(l1,u)+f(u+1,r1)+w(l1,r1)f(l2,r2)≤f(l2,v)+f(v+1,r2)+w(l2,r2)
然后由于 u + 1 ≤ v + 1 ≤ r 1 ≤ r 2 u + 1 \le v + 1 \le r_1 \le r_2 u+1≤v+1≤r1≤r2 和我们给出的假设,又可以得到不等式:
{ f ( u + 1 , r 1 ) + f ( v + 1 , r 2 ) ≤ f ( u + 1 , r 2 ) + f ( v + 1 , r 1 ) w ( l 1 , r 1 ) + w ( l 2 , r 2 ) ≤ w ( l 1 , r 2 ) + w ( l 2 , r 1 ) \begin{cases} f(u + 1, r_1) + f(v + 1, r_2) \le f(u + 1, r_2) + f(v + 1, r_1)\\ w(l_1, r_1) + w(l_2, r_2) \le w(l_1, r_2) + w(l_2, r_1) \end{cases} {f(u+1,r1)+f(v+1,r2)≤f(u+1,r2)+f(v+1,r1)w(l1,r1)+w(l2,r2)≤w(l1,r2)+w(l2,r1)
将前两个不等式相加并代入第三个和第四个不等式可以得到:
f ( l 1 , r 1 ) + f ( l 2 , r 2 ) ≤ f ( l 1 , u ) + f ( l 2 , v ) + f ( u + 1 , r 1 ) + f ( v + 1 , r 2 ) + w ( l 1 , r 1 ) + w ( l 2 , r 2 ) ≤ f ( l 1 , u ) + f ( l 2 , v ) + f ( u + 1 , r 2 ) + f ( v + 1 , r 1 ) + w ( l 1 , r 1 ) + w ( l 2 , r 2 ) ≤ f ( l 1 , u ) + f ( l 2 , v ) + f ( u + 1 , r 2 ) + f ( v + 1 , r 1 ) + w ( l 1 , r 2 ) + w ( l 2 , r 1 ) = [ f ( l 1 , u ) + f ( u + 1 , r 2 ) + w ( l 1 , r 2 ) ] + [ f ( l 2 , v ) + f ( v + 1 , r 1 ) + w ( l 2 , r 1 ) ] = f ( l 1 , r 2 ) + f ( l 2 , r 1 ) \begin{aligned} f(l_1, r_1) + f(l_2, r_2) & \le f(l_1, u) + f(l_2, v) + f(u + 1, r_1) + f(v + 1, r_2) + w(l_1, r_1) + w(l_2, r_2) \\ & \le f(l_1, u) + f(l_2, v) + f(u + 1, r_2) + f(v + 1, r_1) + w(l_1, r_1) + w(l_2, r_2) \\ & \le f(l_1, u) + f(l_2, v) + f(u + 1, r_2) + f(v + 1, r_1) + w(l_1, r_2) + w(l_2, r_1) \\ & = [f(l_1, u) + f(u + 1, r_2) + w(l_1, r_2)] + [f(l_2, v) + f(v + 1, r_1) + w(l_2, r_1)] \\ & = f(l_1, r_2) + f(l_2, r_1) \end{aligned} f(l1,r1)+f(l2,r2)≤f(l1,u)+f(l2,v)+f(u+1,r1)+f(v+1,r2)+w(l1,r1)+w(l2,r2)≤f(l1,u)+f(l2,v)+f(u+1,r2)+f(v+1,r1)+w(l1,r1)+w(l2,r2)≤f(l1,u)+f(l2,v)+f(u+1,r2)+f(v+1,r1)+w(l1,r2)+w(l2,r1)=[f(l1,u)+f(u+1,r2)+w(l1,r2)]+[f(l2,v)+f(v+1,r1)+w(l2,r1)]=f(l1,r2)+f(l2,r1)
情况(2): u > v u > v u>v。显然有 l 1 ≤ v < r 1 , l 2 ≤ u < r 2 l_1 \le v < r_1, l_2 \le u < r_2 l1≤v<r1,l2≤u<r2。
得到不等式组:
{ f ( l 1 , r 1 ) ≤ f ( l 1 , v ) + f ( v + 1 , r 1 ) + w ( l 1 , r 1 ) f ( l 2 , r 2 ) ≤ f ( l 2 , u ) + f ( u + 1 , r 2 ) + w ( l 2 , r 2 ) \begin{cases} f(l_1, r_1) \le f(l_1, v) + f(v + 1, r_1) + w(l_1, r_1) \\ f(l_2, r_2) \le f(l_2, u) + f(u + 1, r_2) + w(l_2, r_2) \end{cases} {f(l1,r1)≤f(l1,v)+f(v+1,r1)+w(l1,r1)f(l2,r2)≤f(l2,u)+f(u+1,r2)+w(l2,r2)
然后根据 l 1 ≤ l 2 ≤ v ≤ u l_1 \le l_2 \le v \le u l1≤l2≤v≤u 和我们的假设得到:
{ f ( l 1 , v ) + f ( l 2 , u ) ≤ f ( l 1 , u ) + f ( l 2 , v ) w ( l 1 , r 1 ) + w ( l 2 , r 2 ) ≤ w ( l 1 , r 2 ) + w ( l 2 , r 1 ) \begin{cases} f(l_1, v) + f(l_2, u) \le f(l_1, u) + f(l_2, v) \\ w(l_1, r_1) + w(l_2, r_2) \le w(l_1, r_2) + w(l_2, r_1) \end{cases} {f(l1,v)+f(l2,u)≤f(l1,u)+f(l2,v)w(l1,r1)+w(l2,r2)≤w(l1,r2)+w(l2,r1)
将两个不等式相加,并将第三个不等式和第四个不等式代入,通过与 情况(1) 相似的变换方法,我们仍然可以得到: f ( l 1 , r 1 ) + f ( l 2 , r 2 ) ≤ f ( l 1 , r 2 ) + f ( l 2 , r 1 ) f(l_1, r_1) + f(l_2, r_2) \le f(l_1, r_2) + f(l_2, r_1) f(l1,r1)+f(l2,r2)≤f(l1,r2)+f(l2,r1)
综上,该 引理 得证。
对于 f ( l , r ) = max k = l r − 1 { f ( l , k ) + f ( k + 1 , r ) } + w ( l , r ) f(l, r) = \max\limits_{k = l}^{r - 1}\{f(l, k) + f(k + 1, r)\} + w(l, r) f(l,r)=k=lmaxr−1{f(l,k)+f(k+1,r)}+w(l,r) 的情况,只需要将上面的不等式的不等号全部换一个方向就是了。
Part.1/3 决策单调性的证明
区间上的决策单调性是指当区间的两个端点中的至少一个向右移动时,其决策点仍在当前位置上或者在当前位置之后。
定理: 若状态 f ( l , r ) f(l, r) f(l,r) 满足四边形不等式,我们记 p ( l , r ) p(l, r) p(l,r) 为其对应的决策点,则一定存在:
p ( l , r − 1 ) ≤ p ( l , r ) ≤ p ( l + 1 , r ) p(l, r - 1) \le p(l, r) \le p(l + 1, r) p(l,r−1)≤p(l,r)≤p(l+1,r)
证明: 这里以 f ( l , r ) = min k = l r − 1 { f ( l , k ) + f ( k + 1 , r ) } + w ( l , r ) f(l, r) = \min\limits_{k = l}^{r - 1} \{f(l, k) + f(k + 1, r)\} + w(l, r) f(l,r)=k=lminr−1{f(l,k)+f(k+1,r)}+w(l,r) 为例, f ( l , r ) = max k = l r − 1 { f ( l , k ) + f ( k + 1 , r ) } + w ( l , r ) f(l, r) = \max\limits_{k = l}^{r - 1} \{f(l, k) + f(k + 1, r)\} + w(l, r) f(l,r)=k=lmaxr−1{f(l,k)+f(k+1,r)}+w(l,r) 可用类似的方法推导。
这里采用反证法来证明这个结论。
令
u
=
p
(
l
,
r
)
,
k
1
=
p
(
l
,
r
−
1
)
,
k
2
=
p
(
l
+
1
,
r
)
u = p(l, r), k_1 = p(l, r - 1), k_2 = p(l + 1, r)
u=p(l,r),k1=p(l,r−1),k2=p(l+1,r),则我们应该证明:
k
1
≤
u
≤
k
2
k_1 \le u \le k_2
k1≤u≤k2。由于证明
k
1
≤
u
k_1 \le u
k1≤u 和证明
u
≤
k
2
u \le k_2
u≤k2 类似,这里只给出
k
1
≤
u
k_1 \le u
k1≤u 的证明。
u
≤
k
2
u \le k_2
u≤k2 的部分请读者自行完成
证明 k 1 ≤ u k_1 \le u k1≤u: 假设有 u < k 1 u < k_1 u<k1,则显然有 u + 1 ≤ k 1 + 1 ≤ r − 1 ≤ r u + 1 \le k_1 + 1 \le r - 1 \le r u+1≤k1+1≤r−1≤r
根据四边形不等式可以得到:
f
(
u
+
1
,
r
−
1
)
+
f
(
k
1
+
1
,
r
)
≤
f
(
u
+
1
,
r
)
+
f
(
k
1
+
1
,
r
−
1
)
f(u + 1, r - 1) + f(k_1 + 1, r) \le f(u + 1, r) + f(k_1 + 1, r - 1)
f(u+1,r−1)+f(k1+1,r)≤f(u+1,r)+f(k1+1,r−1)
又由于 u u u 是区间 [ l , r ] [l, r] [l,r] 的最优决策点,则我们可以得到:
f ( l , u ) + f ( u + 1 , r ) ≤ f ( l , k 1 ) + f ( k 1 + 1 , r ) f(l, u) + f(u + 1, r) \le f(l, k_1) + f(k_1 + 1, r) f(l,u)+f(u+1,r)≤f(l,k1)+f(k1+1,r)
两不等式相加并化简得到:
f ( l , u ) + f ( u + 1 , r − 1 ) ≤ f ( l , k 1 ) + f ( k 1 + 1 , r − 1 ) f(l, u) + f(u + 1, r - 1) \le f(l, k_1) + f(k_1 + 1, r - 1) f(l,u)+f(u+1,r−1)≤f(l,k1)+f(k1+1,r−1)
不难发现若是这种状态的话区间 [ l , r − 1 ] [l, r - 1] [l,r−1] 的决策点应该是 u u u 而不是 k 1 k_1 k1,与假设矛盾,所以必有 k 1 ≤ u k_1 \le u k1≤u。
这样就有决策单调性了。
Part.1/4 时间复杂度的证明
在转移时记录下 p ( l , r ) p(l, r) p(l,r),我们可以将决策点的枚举数量将降为:
∑ 1 ≤ l ≤ r ≤ n p ( l + 1 , r ) − p ( l , r − 1 ) = ∑ i = 1 n p ( i , n ) − p ( 1 , i ) ≤ n 2 \sum\limits_{1 \le l \le r \le n} p(l + 1, r) - p(l, r - 1) = \sum\limits_{i = 1}^{n} p(i, n) - p(1, i) \le n^2 1≤l≤r≤n∑p(l+1,r)−p(l,r−1)=i=1∑np(i,n)−p(1,i)≤n2
所以这样的话时间复杂度就变成了 O ( N 2 ) O(N^2) O(N2) 。
Part.1/5 实现方法
我们可以边转移边记录转移的位置,核心代码如下:
for(int len = 2; len <= N; len++)
for(int i = 1; i <= N - len + 1; i++) {
int j = i + len - 1;
f[i][j] = INF;
for(int k = pos[i][j - 1]; k <= pos[i + 1][j]; k++) {
int val = f[i][k] + f[k + 1][j] + calc_cost(i, j);
if(val < f[i][j]) f[i][j] = val, pos[i][j] = k;
}
}
Part.2 其他模型
如果有我没有找到的模型就在评论区指出一下。
Part.2/1 一维 DP 模型
Part2/1-1 模型概述
将一个由 n n n 个数构成的序列 A i A_i Ai 划分成任意多段,每段的代价为 w ( l , r ) w(l, r) w(l,r)。求最大或者最小代价。
这类 DP 的状态定义一般为 f ( i ) f(i) f(i) 表示将前 i i i 个数划分成任意段数的代价,则(以最小代价为例,最大代价可同理推出)状态转移方程为:
f ( i ) = min j = 1 i − 1 { f ( j ) + w ( j , i ) } f(i) = \min\limits_{j = 1}^{i - 1}\{f(j) + w(j, i)\} f(i)=j=1mini−1{f(j)+w(j,i)}
Part2/1-2 决策单调性的证明
我们记 k 1 k_1 k1 为 f ( i 1 ) f(i_1) f(i1) 的决策点, k 2 k_2 k2 为 f ( i 2 ) f(i_2) f(i2) 的决策点,则我们应该证明:
k 1 ≤ k 2 ≤ i 1 ≤ i 2 k_1 \le k_2 \le i_1 \le i_2 k1≤k2≤i1≤i2
考虑反证法,假设有 k 2 < k 1 < i 1 ≤ i 2 k_2 < k_1 < i_1 \le i_2 k2<k1<i1≤i2,则根据四边形不等式:
w ( k 2 , i 1 ) + w ( k 1 , i 2 ) ≤ w ( k 1 , i 1 ) + w ( k 2 , i 2 ) w(k_2, i_1) + w(k_1, i_2) \le w(k_1, i_1) + w(k_2, i_2) w(k2,i1)+w(k1,i2)≤w(k1,i1)+w(k2,i2)
又因为 k 2 k_2 k2 是 i 1 i_1 i1 的最优决策点,所以应该有:
f ( k 2 ) + w ( k 2 , i 2 ) ≤ f ( k 1 ) + w ( k 1 , i 2 ) f(k_2) + w(k_2, i_2) \le f(k_1) + w(k_1, i_2) f(k2)+w(k2,i2)≤f(k1)+w(k1,i2)
两式相加得到:
f ( k 2 ) + w ( k 2 , i 1 ) ≤ f ( k 1 ) + w ( k 1 , i 1 ) f(k_2) + w(k_2, i_1) \le f(k_1) + w(k_1, i_1) f(k2)+w(k2,i1)≤f(k1)+w(k1,i1)
显然不符合 k 1 k_1 k1 是 i 1 i_1 i1 的最优决策点。这样就有决策单调性了。
Part2/1-3 实现方法——分治
由于我们没办法直接确定每个位置的决策点但可以确定它们所在的区间,所以我们用分治来解决。
void DFS(int lb, int ub, int optl, int optr) {
if(lb > ub) return;
int mid = (lb + ub) >> 1, pos = optl;
f[mid] = calc_cost(pos, mid);
for(int i = optl; i <= optr && i <= mid; i++) {
int tmp = calc_cost(i, mid);
if(tmp < f[mid]) f[mid] = tmp, pos = i;
}
DFS(lb, mid - 1, optl, pos);
DFS(mid + 1, ub, pos, optr);
}
复杂度为 O ( N log 2 N ) O(N \log_2 N) O(Nlog2N)。
Part.2/2 有阶段限制的一维 DP 模型
Part.2/2-1 模型概述
将一个由 n n n 个数构成的序列 A i A_i Ai 划分成 k k k 段,每段的代价为 w ( l , r ) w(l, r) w(l,r),满足 w ( l , r ) w(l, r) w(l,r) 满足四边形不等式,求最小或最大代价和。
这类 DP 的状态定义一般为 f ( i , j ) f(i, j) f(i,j) 表示将前 j j j 个数分成 i i i 段所产生的代价。转移方程式为:(这里仅以最小代价为例,最大代价可类比推出)
f ( i , j ) = min k = 1 j { f ( i − 1 , k − 1 ) + w ( k , j ) } f(i, j) = \min\limits_{k = 1}^{j}\{f(i - 1, k - 1) + w(k, j)\} f(i,j)=k=1minj{f(i−1,k−1)+w(k,j)}
Part.2/2-2 证明决策单调性
其实证明和上面的差不多,只是用到的是上一层的状态罢了。
若 p ( i , j ) p(i, j) p(i,j) 为 f ( i , j ) f(i, j) f(i,j) 的最优决策点,我们可以得到结论:
p ( i − 1 , j ) ≤ p ( i , j ) ≤ p ( i , j + 1 ) p(i - 1, j) \le p(i, j) \le p(i, j + 1) p(i−1,j)≤p(i,j)≤p(i,j+1)
Part.2/2-3 实现方法
Part.2/2-3-1 分治
知道了决策单调性,我们就可以用分治来乱搞了。
定义函数 g ( i , l , r , p l , p r ) g(i, l, r, p_l, p_r) g(i,l,r,pl,pr) 表示当前正在划分第 i i i 段,求解 [ l , r ] [l, r] [l,r] 中的状态值,并且已知这些决策点一定位于 [ p l , p r ] [p_l, p_r] [pl,pr] 中的,然后用上面类似的分治算法:
void DFS(int now, int lb, int ub, int optl, int optr) {
if(lb > ub) return;
int mid = (lb + ub) >> 1, pos;
for(int i = optl; i <= optr && i <= mid; i++) {
ll val = f[now - 1][i - 1] + calc_cost(i, mid);
if(f[now][mid] > val) f[now][mid] = val, pos = i;
}
DFS(now, lb, mid - 1, optl, pos);
DFS(now, mid + 1, ub, pos, optr);
}
//主程序内:
memset(f, 0x3f, sizeof f);
//尤其注意这句话
f[0][0] = 0;
for(int i = 1; i <= K; i++)
DFS(i, 1, N, 1, N);
时间复杂度为 O ( K N log 2 N ) O(K N \log_2 N) O(KNlog2N),空间复杂度可以用滚动数组优化到 O ( N ) O(N) O(N)。
Part.2/2-3-1 枚举
注意倒着做就是了。
for(int i = 0; i <= N; i++)
pos[0][i] = 1, pos[i][N + 1] = N;
//注意这里的神奇初值
memset(f, 0x3f, sizeof f);
f[0][0] = 0;
for(int i = 1; i <= K; i++)
for(int j = N; j >= 1; j--)
for(int k = pos[i - 1][j]; k <= pos[i][j + 1]; k++) {
ll val = f[i - 1][k - 1] + c[k][j];
if(f[i][j] > val) f[i][j] = val, pos[i][j] = k;
}
时间复杂度为 O ( K N ) O(K N) O(KN),空间复杂度为 O ( K N ) O(K N) O(KN)。(不知道可不可以用滚动数组优化一下)
因为博客太长了,我的 XP 已经卡出了一种境界,所以 Part.3 如何证明 w ( l m r ) w(lm r) w(lmr) 满足四边形不等式、Part.4 例题、Part.5 参考实现 就放到了下一篇博客去了。