动态规划加速原理(含代码)

动态规划加速原理

原题目

在一个铁路沿线顺序存放着 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]1ijn所需要的最少费用为: 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:k1],再合并: a [ k : j ] a[k:j] a[k:j]

由此定义必须有 k − 1 ≥ i k-1 \geq i k1i,也即 i < j i<j i<j

同理 k ≤ j k \leq j kj

遍历所有 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<kj{m(i,k1)+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<kj{m(i,k1)+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' iijj时,有:

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' iijj时,如果:

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),iijj

证明如下:

l = j ′ − i l=j'-i l=ji,定义为区间长度。

采用数学归纳法,先证明当 l ≤ 1 l \leq 1 l1时,结论成立

l = 1 , l=1, l=1,则: j ′ − i = 1 j'-i=1 ji=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=ijj

显然,两侧相等,所以成立。

( 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),iij=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({tm(i,j)=m(i,t1)+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,k1)+m(k,j)+w(i,j) ( ∗ ∗ ) (**) ()

这种情形下,因为 k k k j j j的相对关系未知,有两种情况: k > j , k ≤ j k > j,k \leq j k>j,kj

( a ) (a) (a) k ≤ j k \leq j kj时:

由于 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,k1)+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,k1)+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=jk<ji=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,k1)+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,k1)+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,k1)+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,k1)+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{tm(i,j)=m(i,t1)+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({tm(i,j)=m(i,t1)+m(t,j)+w(i,j)},t>i

由于 y , z y,z y,z的大小关系未知,我们分 z ≤ y z\leq y zy z > y z>y z>y分别证明

( a ) z ≤ y (a)z\leq y (a)zy

有: i < z ≤ y < j , i ′ < y ≤ j < j ′ i<z\leq y < j,i'<y \leq j < j' i<zy<j,i<yj<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,z1)+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,y1)+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,y1)+m(y,j)+m(i,z1)+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<zy<j<j

那么: l ′ = j ′ − z < j ′ − i = l l'=j'-z<j'-i=l l=jz<ji=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,y1)+m(y,j)+w(i,j)+m(i,z1)+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,y1)+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,z1)+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,y1)+m(y,j)+w(i,j)+m(i,z1)+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,y1)+m(y,j)+w(i,j)+m(i,z1)+m(z,j)+w(i,j)

考虑 m ( i , y − 1 ) + m ( i ′ , z − 1 ) m(i,y-1)+m(i',z-1) m(i,y1)+m(i,z1)

由于 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<y1<z1,l=z1i<ji=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,y1)+m(i,z1)m(i,z1)+m(i,y1)

( ∗ ∗ ∗ ) (***) ()

≤ 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,z1)+m(z,j)+w(i,j)+m(i,y1)+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{km(i,j)=m(i,k1)+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),ij

(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,k1)+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<kj{m(i,k1)+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 kk 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<kkj

假设:

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 kkj<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),ij

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,k1)+m(i+1,k1)m(i+1,k1)+m(i,k1)

这显然是成立的,因为对于: i < i + 1 ≤ k − 1 ≤ k ′ − 1 i<i+1\leq k - 1 \leq k'-1 i<i+1k1k1

由四边形不等式可得上式。

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' iijj时,

讨论:

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<kj{m(i,k1)+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,j1)ks(i+1,j){m(i,k1)+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=2ni=1nlen+1(1+s[i+1][i+len1]s[i][i+len2])

= ∑ 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(nlen+s[nlen][n]s[1][len1])

≤ ∑ l e n = 2 n ( n − l e n + n − 0 ) \leq \sum _{len=2}^{n}(n-len+n-0) len=2n(nlen+n0)

= O ( n 2 ) =O(n^2) =O(n2)

所以我们把时间复杂度从 O ( n 3 ) O(n^3) O(n3)优化到了 O ( n 2 ) O(n^2) O(n2)

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指针常量

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值