Introduction
Matrix Chain Multiplication (MCM) is one of the most important Dynamic Programming problems. The goal is not to perform the matrix multiplication itself but to determine the most efficient order in which the matrices should be multiplied.
The problem becomes interesting because matrix multiplication is associative:
(A × B) × C = A × (B × C)
However, the number of scalar multiplications required can vary significantly depending on the order of multiplication.
Our task is to find the parenthesization that minimizes the total multiplication cost and return the corresponding bracket representation.
Understanding the Problem
Suppose we have the array:
arr = [40, 20, 30, 10, 30]
This represents the following matrices:
A = 40 × 20
B = 20 × 30
C = 30 × 10
D = 10 × 30
There are multiple ways to multiply these matrices:
((AB)C)D
(A(BC))D
(A(B(CD)))
((A(BC))D)
Each arrangement requires a different number of scalar multiplications.
The objective is to find the arrangement with the minimum cost.
Why Greedy Approaches Fail
A common mistake is to always multiply the cheapest adjacent pair first.
This does not guarantee a globally optimal solution because a locally optimal multiplication may create a large intermediate matrix, increasing future costs.
Since every partition affects subsequent computations, we must evaluate all possible split positions.
This naturally leads to Dynamic Programming.
Dynamic Programming Idea
Let:
dp[i][j]
represent the minimum cost needed to multiply matrices from i to j.
For every range:
i ... j
we try every possible split position:
k
such that:
(i...k) and (k+1...j)
The cost becomes:
Cost of the left subchain
Cost of the right subchain
Cost of multiplying both results
Mathematically:
dp[i][j] =
min(
dp[i][k]
+
dp[k+1][j]
+
arr[i-1] * arr[k] * arr[j]
)
For every optimal split, we store the value of k.
This information will later help us reconstruct the bracket structure.
Tracking the Optimal Split
Besides the DP table, we maintain another table:
split[i][j]
which stores the index k that produced the minimum cost.
Example:
split[1][4] = 3
means the optimal way to multiply matrices from A to D is:
(A..C)(D)
By recursively following these split points, we can rebuild the complete parenthesization.
Building the Answer String
Once the DP table is complete:
A single matrix is represented by a character.
Matrix 1 → A
Matrix 2 → B
Matrix 3 → C
And so on.
For every non-leaf range:
(i, j)

Join the conversation! Your thoughts help the community grow.