首先什么是四边形不等式呢?设w是整数定义下的一个二元函数,形式如下
设
a
≤
b
≤
c
≤
d
设a\leq b\leq c\leq d
设a≤b≤c≤d
有
w
(
a
,
c
)
+
w
(
b
,
d
)
≤
w
(
a
,
d
)
+
w
(
b
,
c
)
有w(a,c)+w(b,d)\leq w(a,d)+w(b,c)
有w(a,c)+w(b,d)≤w(a,d)+w(b,c)
在这个四边形里面,
a
d
+
b
c
>
a
c
+
b
d
ad+bc\gt ac+bd
ad+bc>ac+bd显然成立,为什么?考虑
△
o
a
c
\triangle oac
△oac和
△
o
b
d
\triangle obd
△obd,根据三角形性质,显然有
o
a
+
o
c
>
a
c
oa+oc\gt ac
oa+oc>ac
o
b
+
o
d
>
b
d
ob+od\gt bd
ob+od>bd两边分别相加有
o
a
+
o
d
+
o
c
+
o
b
>
a
c
+
b
d
oa+od+oc+ob\gt ac+bd
oa+od+oc+ob>ac+bd也就是
a
d
+
b
c
>
a
c
+
b
d
ad+bc\gt ac+bd
ad+bc>ac+bd,那什么时候相等,当abcd四点共线的时候相等,这也就是四边形不等式
a
d
+
b
c
≥
a
c
+
b
d
ad+bc\geq ac+bd
ad+bc≥ac+bd
上面的程序是区间DP问题的一般性框架,可以看到,第一圈for循环是区间长度,不可省略,第二圈for循环是区间的左端点,也不能省略,这两圈是必要的,那么唯一可以优化的就是第三圈的for,这个for是在干嘛呢,这个for循环的作用是寻找区间
[
i
,
j
]
[i,j]
[i,j]内的最优分割点,四边形优化就是在这里将
[
i
,
j
]
[i,j]
[i,j]缩小,设
d
p
[
i
,
j
]
dp[i,j]
dp[i,j]表示动态规划的一个状态量,定义
s
[
i
,
j
]
s[i,j]
s[i,j]为
d
p
[
i
,
j
]
dp[i,j]
dp[i,j]取得最小值对应的
k
k
k值,可以证明
s
[
i
]
[
j
−
1
]
≤
s
[
i
]
[
j
]
≤
s
[
i
+
1
]
[
j
]
s[i][j-1]\leq s[i][j]\leq s[i+1][j]
s[i][j−1]≤s[i][j]≤s[i+1][j]也就是
s
[
i
]
[
j
−
1
]
≤
k
≤
s
[
i
+
1
]
[
j
]
s[i][j-1]\leq k\leq s[i+1][j]
s[i][j−1]≤k≤s[i+1][j]利用这个不等式,我们可以将k的枚举范围从
[
i
,
j
]
[i,j]
[i,j]缩小到
[
s
[
i
]
[
j
−
1
]
,
s
[
i
+
1
]
[
j
]
]
[s[i][j-1],s[i+1][j]]
[s[i][j−1],s[i+1][j]],优化后的程序如下
下面讨论的都是取最小值的四边形优化。下面来证明
s
[
i
]
[
j
−
1
]
≤
s
[
i
]
[
j
]
≤
s
[
i
+
1
]
[
j
]
s[i][j-1]\leq s[i][j]\leq s[i+1][j]
s[i][j−1]≤s[i][j]≤s[i+1][j]考虑右侧不等号 设
m
k
[
i
,
j
]
=
m
[
i
,
k
]
+
m
[
k
,
j
]
m_k[i,j]=m[i,k]+m[k,j]
mk[i,j]=m[i,k]+m[k,j]
s
[
i
]
[
j
]
=
d
s[i][j]=d
s[i][j]=d如果说
d
d
d是最优分割,因为取得是最小值,那么应该有
m
k
[
i
,
j
]
≥
m
d
[
i
,
j
]
m_k[i,j]\geq m_d[i,j]
mk[i,j]≥md[i,j]现在
d
d
d是最优分割,那么扩展到下一个区间的时候,
d
d
d也仍然应该是最优分割,也就是
m
k
[
i
+
1
,
j
]
≥
m
d
[
i
+
1
,
j
]
m_k[i+1,j]\geq m_d[i+1,j]
mk[i+1,j]≥md[i+1,j]仍然成立,那么根据数学归纳法,如果能够证明这个式子,也就能够说明
s
[
i
]
[
j
]
≤
s
[
i
+
1
]
[
j
]
s[i][j]\leq s[i+1][j]
s[i][j]≤s[i+1][j],注意根据数学归纳法,我们现在已知条件是
m
k
[
i
,
j
]
≥
m
d
[
i
,
j
]
m_k[i,j]\geq m_d[i,j]
mk[i,j]≥md[i,j],要证明的是
m
k
[
i
+
1
,
j
]
≥
m
d
[
i
+
1
,
j
]
m_k[i+1,j]\geq m_d[i+1,j]
mk[i+1,j]≥md[i+1,j]
将这两个式子整体作差,得到
(
m
k
[
i
+
1
,
j
]
−
m
d
[
i
,
j
]
)
−
(
m
k
[
i
,
j
]
−
m
d
[
i
,
j
]
)
(m_k[i+1,j]-m_d[i,j])-(m_k[i,j]-m_d[i,j])
(mk[i+1,j]−md[i,j])−(mk[i,j]−md[i,j])根据
m
k
[
i
+
1
,
j
]
=
m
[
i
+
1
,
k
]
+
m
[
k
,
j
]
m_k[i+1,j]=m[i+1,k]+m[k,j]
mk[i+1,j]=m[i+1,k]+m[k,j]
m
k
[
i
,
j
]
=
m
[
i
,
k
]
+
m
[
k
,
j
]
m_k[i,j]=m[i,k]+m[k,j]
mk[i,j]=m[i,k]+m[k,j]
m
d
[
i
+
1
,
j
]
=
m
[
i
+
1
,
d
]
+
m
[
d
,
j
]
m_d[i+1,j]=m[i+1,d]+m[d,j]
md[i+1,j]=m[i+1,d]+m[d,j]
m
d
[
i
,
j
]
=
m
[
i
,
d
]
+
m
[
d
,
j
]
m_d[i,j]=m[i,d]+m[d,j]
md[i,j]=m[i,d]+m[d,j]全部代入化简得到
m
[
i
+
1
,
k
]
−
m
[
i
,
k
]
+
m
[
i
,
d
]
−
m
[
i
+
1
,
d
]
m[i+1,k]-m[i,k]+m[i,d]-m[i+1,d]
m[i+1,k]−m[i,k]+m[i,d]−m[i+1,d]因为
i
<
i
+
1
≤
k
≤
d
i\lt i+1\leq k\leq d
i<i+1≤k≤d根据四边形不等式,有
m
[
i
,
k
]
+
m
[
i
+
1
,
d
]
≤
m
[
i
,
d
]
+
m
[
i
+
1
,
k
]
m[i,k]+m[i+1,d]\leq m[i,d]+m[i+1,k]
m[i,k]+m[i+1,d]≤m[i,d]+m[i+1,k]整理得到
m
[
i
+
1.
k
]
−
m
[
i
,
k
]
+
m
[
i
,
d
]
−
m
[
i
+
1
,
d
]
≥
0
m[i+1.k]-m[i,k]+m[i,d]-m[i+1,d]\geq 0
m[i+1.k]−m[i,k]+m[i,d]−m[i+1,d]≥0正好对应刚才的化简结果,而这个结果正好对应着
m
k
[
i
+
1
,
j
]
−
m
k
[
i
,
j
]
≥
m
d
[
i
+
1
,
j
]
−
m
d
[
i
,
j
]
m_k[i+1,j]-m_k[i,j]\geq m_d[i+1,j]-m_d[i,j]
mk[i+1,j]−mk[i,j]≥md[i+1,j]−md[i,j]再移项,回头看一眼已知条件,可以得到
m
k
[
i
+
1
,
j
]
−
m
d
[
i
+
1
,
j
]
≥
m
k
[
i
,
j
]
−
m
d
[
i
,
j
]
≥
0
m_k[i+1,j]-m_d[i+1,j]\geq m_k[i,j]-m_d[i,j]\geq 0
mk[i+1,j]−md[i+1,j]≥mk[i,j]−md[i,j]≥0也就是
m
k
[
i
+
1
,
j
]
≥
m
d
[
i
+
1
,
j
]
m_k[i+1,j]\geq m_d[i+1,j]
mk[i+1,j]≥md[i+1,j]
右侧
≤
\leq
≤证明完成,左侧
≤
\leq
≤证明方式类似,只不过改为考虑
j
j
j而不是
i
i
i
时间复杂度分析
这三层
f
o
r
for
for循环最外侧是
O
(
n
)
O(n)
O(n)的,现在考虑内侧两层
f
o
r
for
for,这里还是以石子合并问题作为例子,但是降低难度,不要环形,改成直线,程序如下
考虑内侧两层
f
o
r
for
for,每个
k
k
k的循环次数是
s
[
i
+
1
[
j
]
−
s
[
i
]
[
j
−
1
]
+
1
s[i+1[j]-s[i][j-1]+1
s[i+1[j]−s[i][j−1]+1次,那么经过
n
−
l
e
n
n-len
n−len次循环过后,内侧两层
f
o
r
for
for循环次数为(累加)
∑
i
=
1
n
−
l
e
n
s
[
i
+
1
]
[
j
]
−
s
[
i
]
[
j
−
1
]
+
1
=
s
[
2
]
[
j
]
−
s
[
n
−
l
e
n
]
[
j
−
1
]
+
n
−
l
e
n
\sum_{i=1}^{n-len}s[i+1][j]-s[i][j-1]+1=s[2][j]-s[n-len][j-1]+n-len
i=1∑n−lens[i+1][j]−s[i][j−1]+1=s[2][j]−s[n−len][j−1]+n−len
=
n
−
l
e
n
+
s
[
2
]
[
j
]
−
s
[
n
−
l
e
n
]
[
j
−
1
]
=n-len+s[2][j]-s[n-len][j-1]
=n−len+s[2][j]−s[n−len][j−1]n后面都是常数,所以内侧两层
f
o
r
for
for的时间复杂度是
O
(
n
)
O(n)
O(n),所以三层
f
o
r
for
for总的时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)