Question : If a chain of matrices is given, we have to find the minimum number of the correct sequence of matrices to multiply.
(ABC)D = (AB)(CD) = A(BCD) = ....(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations
A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.
int solve(int i, int j,int arr[])
{
if(i>=j)return 0;
int ans=INT_MAX;
for(int k=i;k<=j-1;k++)
{
int tempAns = solve(i,k,arr) + solve(k+1,j,arr)
+ arr[i-1]*arr[k]*arr[j];
ans=min(ans,tempAns);
}
return ans;
}
int matrixMultiplication(int N, int arr[])
{
return solve(1,N-1,arr);
}The time complexity of the above naive recursive approach is exponential. Observe that the above function computes the same subproblems again and again.
Let us saywe are given an array of 5 elements that means we are given N-1 i.e 4 matrixes .See the following recursion tree for a matrix chain of size 4.

There are so many overlapping subproblems . Let's optimize it using DP !!
int dp[501][501];
int solve(int i, int j,int arr[])
{
if(i>=j)return 0;
if(dp[i][j]!=-1)
return dp[i][j];
int ans=INT_MAX;
for(int k=i;k<=j-1;k++)
{
int tempAns = solve(i,k,arr) + solve(k+1,j,arr)
+ arr[i-1]*arr[k]*arr[j];
ans=min(ans,tempAns);
}
return dp[i][j] = ans;
}
int matrixMultiplication(int N, int arr[])
{
memset(dp,-1,sizeof(dp));
return solve(1,N-1,arr);
}int MatrixChainOrder(int arr[], int n)
{
/* For simplicity of the program, one
extra row and one extra column are
allocated in arr[][]. 0th row and 0th
column of arr[][] are not used */
int dp[n][n];
int i, j, k, L, q;
/* dp[i, j] = Minimum number of scalar
multiplications needed to compute the
matrix A[i]A[i+1]...A[j] = A[i..j] where
dimension of A[i] is arr[i-1] x arr[i] */
// cost is zero when multiplying
// one matrix.
for (i = 1; i < n; i++)
dp[i][i] = 0;
// L is chain length.
for (L = 2; L < n; L++)
{
for (i = 1; i < n - L + 1; i++)
{
j = i + L - 1;
dp[i][j] = INT_MAX;
for (k = i; k <= j - 1; k++)
{
// q = cost/scalar multiplications
q = dp[i][k] + dp[k + 1][j]
+ arr[i - 1] * arr[k] * arr[j];
if (q < dp[i][j])
dp[i][j] = q;
}
}
}
return dp[1][n - 1];
}