动态规划加速原理
原题目
在一个铁路沿线顺序存放着 n n n堆装满货物的集装箱。货物储运公司要将集装箱有次序地集中为一堆。规定每次只能选择相邻的2堆货物合并成新的一堆,所需要的运输费用和新的一堆中集装箱的数量成正比。
给定各堆的集装箱数量,试制定一个运输方案,使得总运输费用最少。
一、朴素动态规划解法
假设 n n n堆货物依次编号为 1 , 2 , . . . , n 1,2,...,n 1,2,...,n,各堆货物的集装箱数分别为 a [ 1 ] , a [ 2 ] , . . . , a [ n ] a[1],a[2],...,a[n] a[1],a[2],...,a[n]
1.最优子结构性质
对于 a [ 1 : n ] a[1:n] a[1:n]的一个最优的合并方式,设在 a [ k ] a[k] a[k]和 a [ k + 1 ] a[k+1] a[k+1]之间断开,
那么显然最优的方式为:
先把 a [ 1 : k ] a[1:k] a[1:k]合并为一堆,再把 a [ k + 1 : n ] a[k+1:n] a[k+1:n]合并为一堆,然后再把这两堆货物合并为一堆。
必然先使得 a [ 1 : k ] a[1:k] a[1:k]合并为最优, a [ k + 1 : n ] a[k+1:n] a[k+1:n]合并也最优
所以,该问题具有最优子结构性质。
2.状态转移方程
假设合并 a [ i : j ] , 1 ≤ i ≤ j ≤ n a[i:j],1 \leq i \leq j \leq n a[i:j],1≤i≤j≤n所需要的最少费用为: m ( i , j ) m(i,j) m(i,j)
首先考虑边界情况,显然当 i = j i = j i=j时无需合并, m ( i , j ) = 0 m(i,j)=0 m(i,j)=0
对于 i < j i<j i<j时,
假设我们在位置为 k k k处分割,先把左右两边合并为一堆,
也即是先合并: a [ i : k − 1 ] a[i:k-1] a[i:k−1],再合并: a [ k : j ] a[k:j] a[k:j]
由此定义必须有 k − 1 ≥ i k-1 \geq i k−1≥i,也即 i < j i<j i<j
同理 k ≤ j k \leq j k≤j
遍历所有 k k k的取值,最小值即为 m ( i , j ) m(i,j) m(i,j)
于是:
m ( i , j ) = m i n i < k ≤ j { m ( i , k − 1 ) + m ( k , j ) + ∑ t = i j a [ t ] } , i < j m(i,j)=min_{i<k \leq j} \{ m(i,k-1)+m(k,j)+ \sum _{t=i} ^j a[t] \},i<j m(i,j)=mini<k≤j{m(i,k−1)+m(k,j)+∑t=ija[t]},i<j
一般化,可令 w ( i , j ) = ∑ t = i j a [ t ] w(i,j)=\sum _{t=i} ^j a[t] w(i,j)=∑t=ija[t]
上式一般化为:
m ( i , j ) = m i n i < k ≤ j { m ( i , k − 1 ) + m ( k , j ) + w ( i , j ) } , i < j m(i,j)=min_{i<k \leq j} \{ m(i,k-1)+m(k,j)+ w(i,j)\},i<j m(i,j)=mini<k≤j{m(i,k−1)+m(k,j)+w(i,j)},i<j
依照这个方程,时间复杂度为: O ( n 3 ) O(n^3) O(n3)
采用了 A c w i n g Acwing Acwing上的石子合并这题进行测试,链接如下:
实际上,石子合并和集装箱问题完全一样。
#include<bits/stdc++.h>
using namespace std;
const int N = 350;
int a[N], s[N], m[N][N];
int n;
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
//预处理前缀和
for(int i = 1; i <= n; i ++)
s[i] = s[i - 1] + a[i];
//遍历长度
for(int len = 2; len <= n; len ++)
{
//遍历起点
for(int i = 1; i + len - 1 <= n; i ++)
{
//终点
int j = i + len - 1;
m[i][j] = 2e9;
for(int k = i + 1; k <= j; k ++)
{
int sum = s[j] - s[i - 1];
m[i][j] = min(m[i][j], m[i][k - 1] + m[k][j] + sum);
}
}
}
cout << m[1][n] << endl;
return 0;
}
以上代码运行时间为:
103
m
s
103ms
103ms
二、动态规划加速算法
证明过程略微枯燥,不感兴趣的读者可以直接跳到应用部分。
加速算法实现
1.四边形不等式
定义
设函数 w ( i , j ) w(i,j) w(i,j),如果当: i ≤ i ′ ≤ j ≤ j ′ i \leq i' \leq j \leq j' i≤i′≤j≤j′时,有:
w ( i , j ) + w ( i ′ , j ′ ) ≤ w ( i , j ′ ) + w ( i ′ , j ) w(i,j) + w(i',j') \leq w(i,j') + w(i', j) w(i,j)+w(i′,j′)≤w(i,j′)+w(i′,j)
称函数 w ( i , j ) w(i,j) w(i,j)满足四边形不等式。
另外,当 i ≤ i ′ ≤ j ≤ j ′ i \leq i' \leq j \leq j' i≤i′≤j≤j′时,如果:
w ( i ′ , j ) ≤ w ( i , j ′ ) w(i',j) \leq w(i,j') w(i′,j)≤w(i,j′)
称函数 w ( i , j ) w(i,j) w(i,j)满足区间包含关系单调。
2.动态规划加速原理证明
首先证明一个引理:
对于满足四边形不等式的区间包含关系单调函数 w w w,
可推得函数 m m m也满足四边形不等式,也即是:
m ( i , j ) + m ( i ′ , j ′ ) ≤ m ( i , j ′ ) + m ( i ′ , j ) , i ≤ i ′ ≤ j ≤ j ′ m(i,j) + m(i',j') \leq m(i,j') + m(i',j),i \leq i' \leq j \leq j' m(i,j)+m(i′,j′)≤m(i,j′)+m(i′,j),i≤i′≤j≤j′
证明如下:
设 l = j ′ − i l=j'-i l=j′−i,定义为区间长度。
采用数学归纳法,先证明当 l ≤ 1 l \leq 1 l≤1时,结论成立
l = 1 , l=1, l=1,则: j ′ − i = 1 j'-i=1 j′−i=1
此时,必然有:
i = i ′ < j = j ′ i=i'<j=j' i=i′<j=j′或者 i < i ′ = j = j ′ i<i'=j=j' i<i′=j=j′或者 i = i ′ = j < j ′ i=i'=j<j' i=i′=j<j′
一般化,先证明一般情况:
( a ) (a) (a)当 i = i ′ i=i' i=i′时,不等式化为:
m ( i , j ) + m ( i , j ′ ) ≤ m ( i , j ′ ) + m ( i , j ) , i = i ′ ≤ j ≤ j ′ m(i,j) + m(i,j') \leq m(i,j') + m(i,j),i = i' \leq j \leq j' m(i,j)+m(i,j′)≤m(i,j′)+m(i,j),i=i′≤j≤j′
显然,两侧相等,所以成立。
( b ) (b) (b)当 j = j ′ j=j' j=j′时,不等式化为:
m ( i , j ) + m ( i ′ , j ) ≤ m ( i , j ) + m ( i ′ , j ) , i ≤ i ′ ≤ j = j ′ m(i,j) + m(i',j) \leq m(i,j) + m(i',j),i \leq i' \leq j = j' m(i,j)+m(i′,j)≤m(i,j)+m(i′,j),i≤i′≤j=j′
同样地,也是两侧相等,所以成立。
所以, l = 1 l=1 l=1时,四边形不等式成立。
且无需考虑 i = i ′ i=i' i=i′或者 j = j ′ j=j' j=j′的情况。
以下只需考虑 i ≠ i ′ , j ≠ j ′ , l > 1 i \neq i',j \neq j' ,l > 1 i=i′,j=j′,l>1的情况
分两种情形证明之,
(1)情形1: i < i ′ = j < j ′ i<i'=j<j' i<i′=j<j′
此时不等式可以化为:
m ( i , j ) + m ( j , j ′ ) ≤ m ( i , j ′ ) m(i,j)+m(j,j') \leq m(i,j') m(i,j)+m(j,j′)≤m(i,j′) ( ∗ ) (*) (∗)
令 k = m a x ( { t ∣ m ( i , j ′ ) = m ( i , t − 1 ) + m ( t , j ′ ) + w ( i , j ′ ) } ) , t > i k=max(\{t|m(i,j') = m(i,t - 1)+m(t,j') + w(i,j') \}), t >i k=max({t∣m(i,j′)=m(i,t−1)+m(t,j′)+w(i,j′)}),t>i
那么, m ( i , j ′ ) = m ( i , k − 1 ) + m ( k , j ′ ) + w ( i , j ′ ) m(i,j') = m(i,k - 1)+m(k, j') + w(i,j') m(i,j′)=m(i,k−1)+m(k,j′)+w(i,j′) ( ∗ ∗ ) (**) (∗∗)
这种情形下,因为 k k k和 j j j的相对关系未知,有两种情况: k > j , k ≤ j k > j,k \leq j k>j,k≤j
( a ) (a) (a)当 k ≤ j k \leq j k≤j时:
由于 k k k这个划分未必使得 m ( i , j ) m(i,j) m(i,j)最小,所以:
m ( i , j ) + m ( i ′ , j ′ ) ≤ m ( i , k − 1 ) + m ( k , j ) + w ( i , j ) + m ( j , j ′ ) m(i,j)+m(i',j') \leq m(i,k-1)+m(k,j)+w(i,j)+m(j,j') m(i,j)+m(i′,j′)≤m(i,k−1)+m(k,j)+w(i,j)+m(j,j′)
由于 w w w的单调性, w ( i , j ) ≤ w ( i , j ′ ) w(i,j) \leq w(i,j') w(i,j)≤w(i,j′)
所以, ( ∗ ∗ ) ≤ m ( i , k − 1 ) + m ( k , j ) + m ( j , j ′ ) + w ( i , j ′ ) (**) \leq m(i,k-1)+m(k,j)+m(j,j')+w(i,j') (∗∗)≤m(i,k−1)+m(k,j)+m(j,j′)+w(i,j′)
考虑到: m ( k , j ) + m ( j , j ′ ) m(k,j)+m(j,j') m(k,j)+m(j,j′)
其中的 l ′ = j ′ − k < j ′ − i = l l'=j'-k<j'-i=l l′=j′−k<j′−i=l
数学归纳法已经假设 l ′ < l l'<l l′<l时结论成立,于是根据 ( ∗ ) (*) (∗)式以及 l ′ < l l'<l l′<l,有:
m ( k , j ) + m ( j , j ′ ) ≤ m ( k , j ′ ) m(k,j)+m(j,j') \leq m(k,j') m(k,j)+m(j,j′)≤m(k,j′)
所以, ( ∗ ∗ ) ≤ m ( i , k − 1 ) + m ( k , j ′ ) + w ( i , j ′ ) = m ( i , j ′ ) (**) \leq m(i,k-1)+m(k,j')+w(i,j')=m(i,j') (∗∗)≤m(i,k−1)+m(k,j′)+w(i,j′)=m(i,j′)
( b ) (b) (b)当 k > j k> j k>j时:
同 ( a ) (a) (a),由于 k k k这个位置划分未必使得 m ( j , j ′ ) m(j,j') m(j,j′)最小
所以, m ( j , j ′ ) ≤ m ( j , k − 1 ) + m ( k , j ′ ) + w ( j , j ′ ) m(j,j') \leq m(j,k-1)+m(k,j')+w(j,j') m(j,j′)≤m(j,k−1)+m(k,j′)+w(j,j′)
m ( i , j ) + m ( j , j ′ ) m(i,j)+m(j,j') m(i,j)+m(j,j′)
≤ m ( i , j ) + m ( j , k − 1 ) + m ( k , j ′ ) + w ( j , j ′ ) \leq m(i,j)+m(j,k-1)+m(k,j')+w(j,j') ≤m(i,j)+m(j,k−1)+m(k,j′)+w(j,j′)
≤ m ( i , k − 1 ) + m ( k , j ′ ) + w ( i , j ′ ) \leq m(i,k-1)+m(k,j')+w(i,j') ≤m(i,k−1)+m(k,j′)+w(i,j′)
(数学归纳法假设以及 w w w的单调性)
= m ( i , j ′ ) =m(i,j') =m(i,j′)
到此,我们已经证明了 i < i ′ = j < j ′ i<i'=j<j' i<i′=j<j′时,结论成立。
(2)情形2: i < i ′ < j < j ′ i<i'<j<j' i<i′<j<j′
令 y = m a x { t ∣ m ( i ′ , j ) = m ( i ’ , t − 1 ) + m ( t , j ) + w ( i ′ , j ) } , t > i y=max\{ t|m(i',j)=m(i’,t-1)+m(t,j)+w(i',j) \},t>i y=max{t∣m(i′,j)=m(i’,t−1)+m(t,j)+w(i′,j)},t>i
令 z = m a x ( { t ∣ m ( i , j ′ ) = m ( i , t − 1 ) + m ( t , j ′ ) + w ( i , j ′ ) } , t > i ′ z=max(\{t|m(i,j')=m(i,t-1)+m(t,j')+w(i,j') \},t>i' z=max({t∣m(i,j′)=m(i,t−1)+m(t,j′)+w(i,j′)},t>i′
由于 y , z y,z y,z的大小关系未知,我们分 z ≤ y z\leq y z≤y和 z > y z>y z>y分别证明
( a ) z ≤ y (a)z\leq y (a)z≤y
有: i < z ≤ y < j , i ′ < y ≤ j < j ′ i<z\leq y < j,i'<y \leq j < j' i<z≤y<j,i′<y≤j<j′
同样地,由于 z , y z,y z,y这两个位置未必分别使得 m ( i , j ) , m ( i ′ , j ′ ) m(i,j),m(i',j') m(i,j),m(i′,j′)最小
所以:
m ( i , j ) ≤ m ( i , z − 1 ) + m ( z , j ) + w ( i , j ) m(i,j) \leq m(i,z-1)+m(z,j) + w(i,j) m(i,j)≤m(i,z−1)+m(z,j)+w(i,j)
m ( i ′ , j ′ ) ≤ m ( i ′ , y − 1 ) + m ( y , j ′ ) + w ( i ′ , j ′ ) m(i',j') \leq m(i',y-1)+m(y,j')+w(i',j') m(i′,j′)≤m(i′,y−1)+m(y,j′)+w(i′,j′)
且由于 w w w满足:
w ( i , j ) + w ( i ′ , j ′ ) ≤ w ( i , j ′ ) + w ( i ′ , j ) w(i,j)+w(i',j') \leq w(i,j')+w(i',j) w(i,j)+w(i′,j′)≤w(i,j′)+w(i′,j)
所以,
m ( i , j ) + m ( i ′ , j ′ ) m(i,j)+m(i',j') m(i,j)+m(i′,j′)
≤ w ( i , j ) + w ( i ′ , j ′ ) + m ( i ′ , y − 1 ) + m ( y , j ′ ) + m ( i , z − 1 ) + m ( z , j ) \leq w(i,j)+w(i',j')+m(i',y-1)+m(y,j')+m(i,z-1)+m(z,j) ≤w(i,j)+w(i′,j′)+m(i′,y−1)+m(y,j′)+m(i,z−1)+m(z,j)
考虑 m ( z , j ) + m ( y , j ′ ) m(z,j)+m(y,j') m(z,j)+m(y,j′)
由于: i < i ′ < z ≤ y < j < j ′ i<i'<z \leq y < j < j' i<i′<z≤y<j<j′
那么: l ′ = j ′ − z < j ′ − i = l l'=j'-z<j'-i=l l′=j′−z<j′−i=l
数学归纳法假设可知:上式 ≤ m ( z , j ′ ) + m ( y , j ) \leq m(z,j') + m(y,j) ≤m(z,j′)+m(y,j)
代入 m ( i , j ) + m ( i ′ , j ′ ) m(i,j)+m(i',j') m(i,j)+m(i′,j′)
≤ m ( i ′ , y − 1 ) + m ( y , j ) + w ( i ′ , j ) + m ( i , z − 1 ) + m ( z , j ′ ) + w ( i , j ′ ) \leq m(i',y-1)+m(y,j)+w(i',j)+m(i,z-1)+m(z,j')+w(i,j') ≤m(i′,y−1)+m(y,j)+w(i′,j)+m(i,z−1)+m(z,j′)+w(i,j′)
= m ( i , j ′ ) + m ( i ′ , j ) =m(i,j')+m(i',j) =m(i,j′)+m(i′,j)
( b ) z > y (b)z > y (b)z>y
类似地,有: i < i ′ < y < z < j ′ i<i'<y<z<j' i<i′<y<z<j′
且 y < j y<j y<j,
也即: i < y < j , i ′ < z < j ′ i<y<j,i'<z<j' i<y<j,i′<z<j′
由于 y , z y,z y,z这两个位置未必分别使得 m ( i , j ) , m ( i ′ , j ′ ) m(i,j),m(i',j') m(i,j),m(i′,j′)最小,
故:
m ( i , j ) ≤ m ( i , y − 1 ) + m ( y , j ) + w ( i , j ) m(i,j) \leq m(i,y-1)+m(y,j)+w(i,j) m(i,j)≤m(i,y−1)+m(y,j)+w(i,j)
m ( i ′ , j ′ ) ≤ m ( i ′ , z − 1 ) + m ( z , j ′ ) + w ( i ′ , j ′ ) m(i',j')\leq m(i',z-1)+m(z,j')+w(i',j') m(i′,j′)≤m(i′,z−1)+m(z,j′)+w(i′,j′)
同理由于 w w w的性质: w ( i , j ) + w ( i ′ , j ′ ) ≤ w ( i , j ′ ) + w ( i ′ , j ) w(i,j)+w(i',j') \leq w(i,j')+w(i',j) w(i,j)+w(i′,j′)≤w(i,j′)+w(i′,j)
于是:
m ( i , j ) + m ( i ′ , j ′ ) m(i,j)+m(i',j') m(i,j)+m(i′,j′) ( ∗ ∗ ∗ ) (***) (∗∗∗)
≤ m ( i , y − 1 ) + m ( y , j ) + w ( i , j ) + m ( i ′ , z − 1 ) + m ( z , j ′ ) + w ( i ′ , j ′ ) \leq m(i,y-1)+m(y,j)+w(i,j)+m(i',z-1)+m(z,j')+w(i',j') ≤m(i,y−1)+m(y,j)+w(i,j)+m(i′,z−1)+m(z,j′)+w(i′,j′)
≤ m ( i , y − 1 ) + m ( y , j ) + w ( i ′ , j ) + m ( i ′ , z − 1 ) + m ( z , j ′ ) + w ( i , j ′ ) \leq m(i,y-1)+m(y,j)+w(i',j)+m(i',z-1)+m(z,j')+w(i,j') ≤m(i,y−1)+m(y,j)+w(i′,j)+m(i′,z−1)+m(z,j′)+w(i,j′)
考虑 m ( i , y − 1 ) + m ( i ′ , z − 1 ) m(i,y-1)+m(i',z-1) m(i,y−1)+m(i′,z−1)
由于 i < i ′ < y − 1 < z − 1 , l ′ = z − 1 − i < j ′ − i = l i<i'<y-1<z-1,l'=z-1-i<j'-i=l i<i′<y−1<z−1,l′=z−1−i<j′−i=l
所以 m ( i , y − 1 ) + m ( i ′ , z − 1 ) ≤ m ( i , z − 1 ) + m ( i ′ , y − 1 ) m(i,y-1)+m(i',z-1) \leq m(i,z-1)+m(i',y-1) m(i,y−1)+m(i′,z−1)≤m(i,z−1)+m(i′,y−1)
则 ( ∗ ∗ ∗ ) (***) (∗∗∗)式
≤ m ( i , z − 1 ) + m ( z , j ′ ) + w ( i , j ) + m ( i ′ , y − 1 ) + m ( y , j ) + w ( i ′ , j ) \leq m(i,z-1)+m(z,j')+w(i,j)+m(i',y-1)+m(y,j)+w(i',j) ≤m(i,z−1)+m(z,j′)+w(i,j)+m(i′,y−1)+m(y,j)+w(i′,j)
= m ( i , j ′ ) + m ( i ′ , j ) =m(i,j')+m(i',j) =m(i,j′)+m(i′,j)
至此,我们已经根据 w w w的性质证明了 m ( i , j ) m(i,j) m(i,j)的四边形不等式性质。
构造 s ( i , j ) = m a x { k ∣ m ( i , j ) = m ( i , k − 1 ) + m ( k , j ) + w ( i , j ) } s(i,j)=max\{k|m(i,j)=m(i,k-1)+m(k,j)+w(i,j)\} s(i,j)=max{k∣m(i,j)=m(i,k−1)+m(k,j)+w(i,j)}
以下证明: s ( i , j ) ≤ s ( i , j + 1 ) ≤ s ( i + 1 , j + 1 ) , i ≤ j s(i,j) \leq s(i,j + 1) \leq s(i+1, j+1),i \leq j s(i,j)≤s(i,j+1)≤s(i+1,j+1),i≤j
(1) i = j i=j i=j时,显然成立;
(2) i < j i < j i<j时,
记: m k ( i , j ) = m ( i , k − 1 ) + m ( k , j ) + w ( i , j ) m_k(i,j)=m(i,k-1)+m(k,j)+w(i,j) mk(i,j)=m(i,k−1)+m(k,j)+w(i,j)
首先证明 s ( i , j ) ≤ s ( i , j + 1 ) s(i,j) \leq s(i,j+1) s(i,j)≤s(i,j+1)
为了说明这一点,我们可以这样思考,
由于, m ( i , j ) = m i n i < k ≤ j { m ( i , k − 1 ) + m ( k , j ) + ∑ t = i j a [ t ] } , i < j m(i,j)=min_{i<k \leq j} \{ m(i,k-1)+m(k,j)+ \sum _{t=i} ^j a[t] \},i<j m(i,j)=mini<k≤j{m(i,k−1)+m(k,j)+∑t=ija[t]},i<j
考虑 m k ( i , j ) m_k(i,j) mk(i,j),从 k = i + 1 k=i+1 k=i+1开始考虑,
只要存在 k ′ ≥ k k' \geq k k′≥k且 m k ′ ( i , j ) ≤ m ( i , j ) m_{k'}(i,j) \leq m(i,j) mk′(i,j)≤m(i,j)
我们可以把 s ( i , j ) s(i,j) s(i,j)更新为 k ′ k' k′
对于区间 [ i , j + 1 ] [i,j+1] [i,j+1]也是同理的,
只要对所有 i < k ≤ k ′ ≤ j i<k \leq k' \leq j i<k≤k′≤j
假设:
m k ′ ( i , j ) ≤ m k ( i , j ) m_{k'}(i,j) \leq m_k(i,j) mk′(i,j)≤mk(i,j)能推导出 m k ′ ( i , j + 1 ) ≤ m k ( i , j + 1 ) m_{k'}(i,j+1) \leq m_{k}(i,j+1) mk′(i,j+1)≤mk(i,j+1)
那么从 i + 1 i+1 i+1开始考虑,只要更新 s ( i , j ) s(i,j) s(i,j)必然可以更新 s ( i , j + 1 ) s(i,j+1) s(i,j+1)
就证明了 s ( i , j ) ≤ s ( i , j + 1 ) s(i,j) \leq s(i,j+1) s(i,j)≤s(i,j+1)
以下证明上述假设成立:
加强为: m k ( i , j ) − m k ′ ( i , j ) ≤ m k ( i , j + 1 ) − m k ′ ( i , j + 1 ) m_k(i,j)-m_{k'}(i,j) \leq m_k(i,j+1) - m_{k'}(i,j+1) mk(i,j)−mk′(i,j)≤mk(i,j+1)−mk′(i,j+1)
也即: m k ( i , j ) + m k ′ ( i , j + 1 ) ≤ m k ( i , j + 1 ) + m k ′ ( i , j ) m_k(i,j)+m_{k'}(i,j+1) \leq m_k(i,j+1) + m_{k'}(i,j) mk(i,j)+mk′(i,j+1)≤mk(i,j+1)+mk′(i,j)
将定义式代入,有:
m ( k , j ) + m ( k ′ , j + 1 ) ≤ m ( k , j + 1 ) + m ( k ′ , j ) m(k,j)+m(k',j+1) \leq m(k,j+1) + m(k',j) m(k,j)+m(k′,j+1)≤m(k,j+1)+m(k′,j)
这是显然的,因为对于 k ≤ k ′ ≤ j < j + 1 k \leq k' \leq j < j + 1 k≤k′≤j<j+1
由四边形不等式可得上式。
同理可证明: s ( i , j + 1 ) ≤ s ( i + 1 , j + 1 ) , i ≤ j s(i,j + 1) \leq s(i+1, j+1),i \leq j s(i,j+1)≤s(i+1,j+1),i≤j
m k ( i , j + 1 ) − m k ′ ( i , j + 1 ) ≤ m k ( i + 1 , j + 1 ) − m k ′ ( i + 1 , j + 1 ) m_k(i,j+1)-m_{k'}(i,j+1) \leq m_k(i+1,j+1)-m_{k'}(i+1,j+1) mk(i,j+1)−mk′(i,j+1)≤mk(i+1,j+1)−mk′(i+1,j+1)
也即是:
m k ( i , j + 1 ) + m k ′ ( i + 1 , j + 1 ) ≤ m k ( i + 1 , j + 1 ) + m k ′ ( i , j + 1 ) m_k(i,j+1)+m_{k'}(i+1,j+1) \leq m_k(i+1,j+1) +m_{k'}(i,j+1) mk(i,j+1)+mk′(i+1,j+1)≤mk(i+1,j+1)+mk′(i,j+1)
将定义代入,有:
m ( i , k − 1 ) + m ( i + 1 , k ′ − 1 ) ≤ m ( i + 1 , k − 1 ) + m ( i , k ′ − 1 ) m(i,k-1)+m(i+1,k'-1) \leq m(i+1,k-1)+m(i,k'-1) m(i,k−1)+m(i+1,k′−1)≤m(i+1,k−1)+m(i,k′−1)
这显然是成立的,因为对于: i < i + 1 ≤ k − 1 ≤ k ′ − 1 i<i+1\leq k - 1 \leq k'-1 i<i+1≤k−1≤k′−1
由四边形不等式可得上式。
3.加速算法证明
根据前面的讨论,
当 w w w是满足四边形不等式的单调函数时,函数 s ( i , j ) s(i,j) s(i,j)单调
显然, w ( i , j ) = ∑ t = i j a [ t ] w(i,j)=\sum _{t=i}^j a[t] w(i,j)=∑t=ija[t]是满足四边形不等式的单调函数
简单证明之:
i ≤ i ′ ≤ j ≤ j ′ i\leq i' \leq j \leq j' i≤i′≤j≤j′时,
讨论:
j = j ′ j=j' j=j′时, w ( i , j ) = w ( i , j ′ ) w(i,j) = w(i,j') w(i,j)=w(i,j′)
j < j ′ j<j' j<j′时, w ( i , j ′ ) = w ( i , j ) + w ( j + 1 , j ′ ) ≥ w ( i , j ) w(i,j')=w(i,j)+w(j+1,j') \geq w(i,j) w(i,j′)=w(i,j)+w(j+1,j′)≥w(i,j)
可得: w ( i , j ′ ) ≥ w ( i , j ) w(i,j') \geq w(i,j) w(i,j′)≥w(i,j)
同理, w ( i , j ) ≥ w ( i ′ , j ) w(i,j )\geq w(i',j) w(i,j)≥w(i′,j)
所以 w ( i , j ′ ) ≥ w ( i , j ) ≥ w ( i ′ , j ) w(i,j') \geq w(i,j) \geq w(i',j) w(i,j′)≥w(i,j)≥w(i′,j)
故满足单调性。
而,
w
(
i
,
j
)
+
w
(
i
′
,
j
′
)
w(i,j)+w(i',j')
w(i,j)+w(i′,j′)
=
w
(
i
,
j
)
+
w
(
j
+
1
,
j
′
)
+
w
(
i
′
,
j
)
=w(i,j)+w(j+1,j')+w(i',j)
=w(i,j)+w(j+1,j′)+w(i′,j)
=
w
(
i
,
j
′
)
+
w
(
i
′
,
j
)
=w(i,j')+w(i',j)
=w(i,j′)+w(i′,j)
所以满足四边形性质。
从而:
m i n i < k ≤ j { m ( i , k − 1 ) + m ( k , j ) } min_{i<k \leq j} \{m(i,k-1)+m(k,j)\} mini<k≤j{m(i,k−1)+m(k,j)}
= m i n s ( i , j − 1 ) ≤ k ≤ s ( i + 1 , j ) { m ( i , k − 1 ) + m ( k , j ) } =min_{s(i,j-1)\leq k \leq s(i+1,j)} \{m(i,k-1)+m(k,j) \} =mins(i,j−1)≤k≤s(i+1,j){m(i,k−1)+m(k,j)}
考虑 s s s数组的初始化:
特殊地,考虑 i = j i=j i=j时,
s ( i , j ) s(i,j) s(i,j)应该是下一次更新 s ( i , j + 1 ) s(i,j+1) s(i,j+1)所要使用的下标下界,
其下界至少从 i i i开始取值,
因此可初始化为 s ( i , i ) = i s(i,i)=i s(i,i)=i
4.加速算法实现
由上,我们得到了加速算法的核心部分:
定义s[i][j]
表示
i
i
i到
j
j
j的最优断开点
且初始化为:s[i][i]=i
题目链接:石子合并
完整实现如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 310;
int a[N], sum[N], n;
int m[N][N], s[N][N];
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
//预处理前缀和
for(int i = 1; i <= n; i ++)
sum[i] = sum[i - 1] + a[i];
//初始化s[]
for(int i = 1; i <= n; i ++)
{
s[i][i] = i;
}
//遍历长度
for(int len = 2; len <= n; len ++)
{
//遍历起点
for(int i = 1; i + len - 1 <= n; i ++)
{
int j = i + len - 1;//右端点
//k的遍历区间为:[l ~ r]
int l = s[i][j - 1], r = s[i + 1][j];
m[i][j] = m[i][l - 1] + m[l][j];
s[i][j] = l;
for(int k = l + 1; k <= r; k ++)
{
int t = m[i][k - 1] + m[k][j];
if(t <= m[i][j])
{
m[i][j] = t;
s[i][j] = k;
}
}
m[i][j] += sum[j] - sum[i - 1];
}
}
cout << m[1][n] << endl;
return 0;
}
运行时间显著优化到
26
m
s
26ms
26ms
时间复杂度分析
计算时间为:
∑
l
e
n
=
2
n
∑
i
=
1
n
−
l
e
n
+
1
(
1
+
s
[
i
+
1
]
[
i
+
l
e
n
−
1
]
−
s
[
i
]
[
i
+
l
e
n
−
2
]
)
\sum _{len=2} ^n \sum _{i=1} ^{n-len+1} (1+s[i+1][i+len-1]-s[i][i+len-2])
∑len=2n∑i=1n−len+1(1+s[i+1][i+len−1]−s[i][i+len−2])
= ∑ l e n = 2 n ( n − l e n + s [ n − l e n ] [ n ] − s [ 1 ] [ l e n − 1 ] ) =\sum _{len=2} ^n (n-len+s[n-len][n]-s[1][len-1]) =∑len=2n(n−len+s[n−len][n]−s[1][len−1])
≤ ∑ l e n = 2 n ( n − l e n + n − 0 ) \leq \sum _{len=2}^{n}(n-len+n-0) ≤∑len=2n(n−len+n−0)
= O ( n 2 ) =O(n^2) =O(n2)
所以我们把时间复杂度从 O ( n 3 ) O(n^3) O(n3)优化到了 O ( n 2 ) O(n^2) O(n2)