Matrix Chain Multiplication in DSA C++ - Time & Space Complexity
We want to understand how the time needed to solve the Matrix Chain Multiplication problem grows as the number of matrices increases.
Specifically, how the number of calculations changes when we try to find the best way to multiply many matrices.
Analyze the time complexity of the following code snippet.
int matrixChainOrder(int dims[], int n) {
int dp[n][n];
for (int i = 1; i < n; i++)
dp[i][i] = 0;
for (int length = 2; length <= n - 1; length++) {
for (int i = 1; i <= n - length; i++) {
int j = i + length - 1;
dp[i][j] = INT_MAX;
for (int k = i; k < j; k++) {
int cost = dp[i][k] + dp[k+1][j] + dims[i-1]*dims[k]*dims[j];
if (cost < dp[i][j]) dp[i][j] = cost;
}
}
}
return dp[1][n-1];
}
This code finds the minimum number of scalar multiplications needed to multiply a chain of matrices.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The triple nested loops that check all ways to split the matrix chain.
- How many times: The outer two loops run roughly n² times, and the innermost loop runs up to n times for each pair, making about n³ operations.
As the number of matrices (n) grows, the number of calculations grows much faster because we try many ways to split the chain.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 1,000 |
| 100 | About 1,000,000 |
| 1000 | About 1,000,000,000 |
Pattern observation: The operations grow roughly by the cube of the input size, so doubling n makes the work about eight times bigger.
Time Complexity: O(n³)
This means the time needed grows roughly with the cube of the number of matrices, so more matrices make the problem much harder.
[X] Wrong: "Since we use dynamic programming, the time must be linear or quadratic."
[OK] Correct: The problem requires checking all pairs and splits, which leads to three nested loops, so the time is cubic, not just linear or quadratic.
Understanding this time complexity helps you explain why some problems need more work even with smart methods, showing your grasp of algorithm efficiency.
"What if we used recursion without memoization? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem objective
The Matrix Chain Multiplication problem aims to find the best way to multiply matrices to minimize computation.Step 2: Identify the correct goal
The goal is to minimize the number of scalar multiplications, not just multiply or count matrices.Final Answer:
To find the minimum number of scalar multiplications needed to multiply a chain of matrices -> Option CQuick Check:
Goal = Minimum multiplications [OK]
- Thinking the goal is to multiply matrices directly without optimization
- Confusing counting matrices with minimizing operations
- Assuming maximum multiplications is the goal
Solution
Step 1: Understand the dimensions array format
For n matrices, the dimensions array has n+1 elements representing rows and columns of each matrix.Step 2: Apply to given matrices
For matrices 10x20, 20x30, 30x40, 40x50, dims = {10, 20, 30, 40, 50}.Final Answer:
int dims[] = {10, 20, 30, 40, 50}; -> Option AQuick Check:
Dimensions array length = number of matrices + 1 [OK]
- Using fewer elements than needed in the dimensions array
- Including extra unrelated numbers
- Confusing matrix dimensions order
int dims[] = {5, 10, 3, 12, 5};
int n = 4;
int m[5][5] = {0};
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = 1000000;
for (int k = i; k < j; k++) {
int cost = m[i][k] + m[k+1][j] + dims[i-1]*dims[k]*dims[j];
if (cost < m[i][j]) m[i][j] = cost;
}
}
}
std::cout << m[1][n] << std::endl;Solution
Step 1: Understand matrix dimensions and indices
Dimensions: 5x10, 10x3, 3x12, 12x5; n=4 matrices; m[i][j] stores min cost from i to j.Step 2: Calculate minimum multiplication cost
Length 2: m[1][2]=150, m[2][3]=360, m[3][4]=180
Length 3: m[1][3]=min(0+360+600,150+0+180)=330; m[2][4]=min(0+180+150,360+0+600)=330
Length 4: m[1][4]=min(0+330+250,150+180+75,330+0+300)=405Final Answer:
405 -> Option DQuick Check:
Minimum cost = 405 [OK]
- Mixing up indices i, j, k
- Incorrect cost formula application
- Forgetting to initialize m[i][j] to max
int dims[] = {40, 20, 30, 10, 30};
int n = 4;
int m[5][5];
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = 0;
for (int k = i; k < j; k++) {
int cost = m[i][k] + m[k+1][j] + dims[i-1]*dims[k]*dims[j];
if (cost < m[i][j])
m[i][j] = cost;
}
}
}Solution
Step 1: Identify initialization mistake
m[i][j] is set to 0 before checking for minimum cost, which causes incorrect comparisons.Step 2: Correct initialization
m[i][j] should be initialized to a very large number (INT_MAX) to find minimum cost correctly.Final Answer:
Initialize m[i][j] to INT_MAX instead of 0 before inner loop -> Option BQuick Check:
Use INT_MAX to find minimum cost [OK]
- Setting m[i][j] to 0 instead of INT_MAX
- Incorrect dims indexing causing wrong cost
- Ignoring initialization leading to wrong min
Solution
Step 1: List matrix dimensions and possible splits
Matrices: A1(10x15), A2(15x20), A3(20x25), A4(25x30). dims=[10,15,20,25,30]. Calculate costs for chain length 2 to 4.Step 2: Calculate minimum costs for each subchain
Length 2: m[1][2]=10*15*20=3000; m[2][3]=15*20*25=7500; m[3][4]=20*25*30=15000
Length 3: m[1][3]=min(0+7500+10*15*25=11250, 3000+0+10*20*25=8000)=8000;
m[2][4]=min(0+15000+15*20*30=24000, 7500+0+15*25*30=18750)=18750
Length 4: m[1][4]=min(0+18750+10*15*30=23250, 3000+15000+10*20*30=24000, 8000+0+10*25*30=15500)=15500Final Answer:
15500 -> Option AQuick Check:
Minimum scalar multiplications = 15500 [OK]
- Incorrectly calculating subproblems costs
- Mixing up matrix dimensions in cost formula
- Not checking all split points k
Ready to prove it?
Pass the test and this pattern moves unknown
