矩阵乘法满足结合律,但不同括号化顺序的计算量可能差几个数量级。矩阵链乘法要找的不是乘积本身,而是最便宜的计算顺序。
设
Ai 的维度为 pi−1×pi,1≤i≤n.
一个 a×b 矩阵乘以 b×c 矩阵,需要 abc 次标量乘法。
1. 为什么贪心不可靠
“先乘眼前代价最小的一对”只看当前一步,却改变了中间矩阵的维度,可能让后续代价暴涨。真正需要考虑的是整个区间在最后一次乘法处怎样切开。
2. 状态与转移
令
m[i][j]=AiAi+1⋯Aj 的最少乘法次数.
若最后一次把区间分在 k 与 k+1 之间,那么左右两侧先各自算完,再把一个 pi−1×pk 矩阵与 pk×pj 矩阵相乘:
m[i][j]=i≤k<jmin{m[i][k]+m[k+1][j]+pi−1pkpj}.
单个矩阵无需乘法:m[i][i]=0。
3. 填表顺序
状态依赖更短区间,所以按区间长度递增:
for length = 2..n:
for i = 1..n-length+1:
j = i + length - 1
m[i][j] = infinity
for k = i..j-1:
try split k
共有 O(n2) 个区间,每个枚举 O(n) 个分割点:
T=O(n3),S=O(n2).
4. 一个直观例子
设
A1:10×100,A2:100×5,A3:5×50.
两种括号化:
(A1A2)A3:10⋅100⋅5+10⋅5⋅50=7500,
A1(A2A3):100⋅5⋅50+10⋅100⋅50=75000.
结果相同,代价却相差十倍。
5. 恢复最优括号化
另设 s[i][j] 记录取得最小值的分割点 k。递归输出:
- i=j 时输出 Ai;
- 否则输出左括号、区间 [i,s[i][j]]、区间 [s[i][j]+1,j]、右括号。
若多个 k 同价,可任选一个;若要求所有最优方案,则要保留全部最优分割点。
6. 正确性
最优括号化的最后一次乘法必定把矩阵链分成两个连续子链。如果任一子链不是自身最优的,就能替换成更便宜的括号化,使总成本更低,矛盾。因此枚举最后分割点覆盖所有最优可能。
7. 区间 DP 的识别方式
矩阵链乘法代表一类常见模型:
- 状态是一段连续区间;
- 决策是选一个分割点;
- 大区间由左右小区间合并;
- 按区间长度递增计算。
石子合并、最优三角剖分、括号匹配计数等题也常用这套结构。