Prerequisite : Dynamic Programming | Set 8 (Matrix Chain Multiplication)
Given a sequence of matrices, find the most efficient way to multiply these matrices together. The problem is not actually to perform the multiplications, but merely to decide in which order to perform the multiplications.
We have many options to multiply a chain of matrices because matrix multiplication is associative. In other words, no matter how we parenthesize the product, the result will be the same. For example, if we had four matrices A, B, C, and D, we would have:
(ABC)D = (AB)(CD) = A(BCD) = ....
However, the order in which we parenthesize the product affects the number of simple arithmetic operations needed to compute the product, or the efficiency. For example, suppose A is a 10 × 30 matrix, B is a 30 × 5 matrix, and C is a 5 × 60 matrix. Then,
(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations
A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.
Clearly the first parenthesization requires less number of operations.
Given an array p[] which represents the chain of matrices such that the ith matrix Ai is of dimension p[i-1] x p[i]. We need to write a function MatrixChainOrder() that should return the minimum number of multiplications needed to multiply the chain.
Input: p[] = {40, 20, 30, 10, 30}
Output: Optimal parenthesization is ((A(BC))D)
Optimal cost of parenthesization is 26000
There are 4 matrices of dimensions 40x20, 20x30,
30x10 and 10x30. Let the input 4 matrices be A, B,
C and D. The minimum number of multiplications are
obtained by putting parenthesis in following way
(A(BC))D --> 20*30*10 + 40*20*10 + 40*10*30
Input: p[] = {10, 20, 30, 40, 30}
Output: Optimal parenthesization is (((AB)C)D)
Optimal cost of parenthesization is 30000
There are 4 matrices of dimensions 10x20, 20x30,
30x40 and 40x30. Let the input 4 matrices be A, B,
C and D. The minimum number of multiplications are
obtained by putting parenthesis in following way
((AB)C)D --> 10*20*30 + 10*30*40 + 10*40*30
Input: p[] = {10, 20, 30}
Output: Optimal parenthesization is (AB)
Optimal cost of parenthesization is 6000
There are only two matrices of dimensions 10x20
and 20x30. So there is only one way to multiply
the matrices, cost of which is 10*20*30
This problem is mainly an extension of previous post. In the previous post, we have discussed algorithm for finding optimal cost only. Here we need print parenthesization also.
The idea is to store optimal break point for every subexpression (i, j) in a 2D array bracket[n][n]. Once we have bracket array us constructed, we can print parenthesization using below code.
// Prints parenthesization in subexpression (i, j)
printParenthesis(i, j, bracket[n][n], name)
{
// If only one matrix left in current segment
if (i == j)
{
print name;
name++;
return;
}
print "(";
// Recursively put brackets around subexpression
// from i to bracket[i][j].
printParenthesis(i, bracket[i][j], bracket, name);
// Recursively put brackets around subexpression
// from bracket[i][j] + 1 to j.
printParenthesis(bracket[i][j]+1, j, bracket, name);
print ")";
}
Below is the implementation of the above steps.
C++
#include <bits/stdc++.h>
using namespace std;
void printParenthesis( int i, int j, int n, int * bracket,
char & name)
{
if (i == j) {
cout << name++;
return ;
}
cout << "(" ;
printParenthesis(i, *((bracket + i * n) + j), n,
bracket, name);
printParenthesis(*((bracket + i * n) + j) + 1, j, n,
bracket, name);
cout << ")" ;
}
void matrixChainOrder( int p[], int n)
{
int m[n][n];
int bracket[n][n];
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] = INT_MAX;
for ( int k = i; k <= j - 1; k++)
{
int q = m[i][k] + m[k + 1][j]
+ p[i - 1] * p[k] * p[j];
if (q < m[i][j])
{
m[i][j] = q;
bracket[i][j] = k;
}
}
}
}
char name = 'A' ;
cout << "Optimal Parenthesization is : " ;
printParenthesis(1, n - 1, n, ( int *)bracket, name);
cout << "\nOptimal Cost is : " << m[1][n - 1];
}
int main()
{
int arr[] = { 40, 20, 30, 10, 30 };
int n = sizeof (arr) / sizeof (arr[0]);
matrixChainOrder(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static char name;
static void printParenthesis( int i, int j, int n,
int [][] bracket)
{
if (i == j) {
System.out.print(name++);
return ;
}
System.out.print( "(" );
printParenthesis(i, bracket[i][j], n, bracket);
printParenthesis(bracket[i][j] + 1 , j, n, bracket);
System.out.print( ")" );
}
static void matrixChainOrder( int p[], int n)
{
int [][] m = new int [n][n];
int [][] bracket = new int [n][n];
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] = Integer.MAX_VALUE;
for ( int k = i; k <= j - 1 ; k++) {
int q = m[i][k] + m[k + 1 ][j]
+ p[i - 1 ] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
bracket[i][j] = k;
}
}
}
}
name = 'A' ;
System.out.print( "Optimal Parenthesization is : " );
printParenthesis( 1 , n - 1 , n, bracket);
System.out.print( "\nOptimal Cost is : "
+ m[ 1 ][n - 1 ]);
}
public static void main(String[] args)
{
int arr[] = { 40 , 20 , 30 , 10 , 30 };
int n = arr.length;
matrixChainOrder(arr, n);
}
}
|
Python3
name = 0 ;
def printParenthesis(i , j, n, bracket):
global name
if (i = = j):
print (name, end = "");
name = chr ( ord (name) + 1 )
return ;
print ( "(" , end = "");
printParenthesis(i, bracket[i][j], n, bracket);
printParenthesis(bracket[i][j] + 1 , j, n, bracket);
print ( ")" , end = "");
def matrixChainOrder( p , n):
global name
m = [ [ 0 for _ in range (n)] for _ in range (n)]
bracket = [ [ 0 for _ in range (n)] for _ in range (n)]
for i in range ( 1 , n):
m[i][i] = 0 ;
for L in range ( 2 , n):
for i in range ( 1 , n - L + 1 ):
j = i + L - 1 ;
m[i][j] = 10 * * 8 ;
for k in range (i, j):
q = m[i][k] + m[k + 1 ][j] + p[i - 1 ] * p[k] * p[j];
if (q < m[i][j]) :
m[i][j] = q;
bracket[i][j] = k;
name = 'A' ;
print ( "Optimal Parenthesization is : " );
printParenthesis( 1 , n - 1 , n, bracket);
print ( "\nOptimal Cost is :" , m[ 1 ][n - 1 ]);
arr = [ 40 , 20 , 30 , 10 , 30 ];
n = len (arr);
matrixChainOrder(arr, n);
|
C#
using System;
class GFG{
static char name;
static void printParenthesis( int i, int j,
int n, int [,] bracket)
{
if (i == j)
{
Console.Write(name++);
return ;
}
Console.Write( "(" );
printParenthesis(i, bracket[i, j], n, bracket);
printParenthesis(bracket[i, j] + 1, j, n, bracket);
Console.Write( ")" );
}
static void matrixChainOrder( int []p, int n)
{
int [,] m = new int [n, n];
int [,] bracket = new int [n, n];
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] = int .MaxValue;
for ( int k = i; k <= j - 1; k++)
{
int q = m[i, k] + m[k + 1, j] +
p[i - 1] * p[k] * p[j];
if (q < m[i, j])
{
m[i, j] = q;
bracket[i, j] = k;
}
}
}
}
name = 'A' ;
Console.Write( "Optimal Parenthesization is : " );
printParenthesis(1, n - 1, n, bracket);
Console.Write( "\nOptimal Cost is : " + m[1, n - 1]);
}
public static void Main(String[] args)
{
int []arr = { 40, 20, 30, 10, 30 };
int n = arr.Length;
matrixChainOrder(arr, n);
}
}
|
Javascript
<script>
var name=0;
function printParenthesis(i , j, n, bracket)
{
if (i == j)
{
document.write(name++);
return ;
}
document.write( "(" );
printParenthesis(i, bracket[i][j], n, bracket);
printParenthesis(bracket[i][j] + 1, j, n, bracket);
document.write( ")" );
}
function matrixChainOrder( p , n)
{
var m = Array(n).fill(0).map(x => Array(n).fill(0));
var bracket = Array(n).fill(0).map(x => Array(n).fill(0));
for ( var i = 1; i < n; i++)
m[i][i] = 0;
for ( var L = 2; L < n; L++)
{
for ( var i = 1; i < n - L + 1; i++)
{
var j = i + L - 1;
m[i][j] = Number.MAX_VALUE;
for ( var k = i; k <= j - 1; k++)
{
var q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j])
{
m[i][j] = q;
bracket[i][j] = k;
}
}
}
}
name = 'A' ;
document.write( "Optimal Parenthesization is : " );
printParenthesis(1, n - 1, n, bracket);
document.write( "\nOptimal Cost is : " + m[1][n - 1]);
}
var arr = [ 40, 20, 30, 10, 30 ];
var n = arr.length;
matrixChainOrder(arr, n);
</script>
|
OutputOptimal Parenthesization is : ((A(BC))D)
Optimal Cost is : 26000
Time Complexity: O(n3)
Auxiliary Space: O(n2)
Another Approach:
This solution try to solve the problem using Recursion using permutations.
Let's take example: {40, 20, 30, 10, 30}
n = 5
Let’s divide that into a Matrix
[ [40, 20], [20, 30], [30, 10], [10, 30] ]
[ A , B , C , D ]
it contains 4 matrices i.e. (n - 1)
We have 3 combinations to multiply i.e. (n-2)
AB or BC or CD
Algorithm:
1) Given array of matrices with length M, Loop through M – 1 times
2) Merge consecutive matrices in each loop
for (int i = 0; i < M - 1; i++) {
int cost = (matrices[i][0] *
matrices[i][1] * matrices[i+1][1]);
// STEP - 3
// STEP - 4
}
3) Merge the current two matrices into one, and remove merged matrices list from list.
If A, B merged, then A, B must be removed from the List
and NEW matrix list will be like
newMatrices = [ AB, C , D ]
We have now 3 matrices, in any loop
Loop#1: [ AB, C, D ]
Loop#2: [ A, BC, D ]
Loop#3 [ A, B, CD ]
4) Repeat: Go to STEP – 1 with newMatrices as input M — recursion
5) Stop recursion, when we get 2 matrices in the list.
Workflow
Matrices are reduced in following way,
and cost’s must be retained and summed-up during recursion with previous values of each parent step.
[ A, B , C, D ]
[(AB), C, D ]
[ ((AB)C), D ]--> [ (((AB)C)D) ]
- return & sum-up total cost of this step.
[ (AB), (CD)] --> [ ((AB)(CD)) ]
- return .. ditto..
[ A, (BC), D ]
[ (A(BC)), D ]--> [ ((A(BC))D) ]
- return
[ A, ((BC)D) ]--> [ (A((BC)D)) ]
- return
[ A, B, (CD) ]
[ A, (B(CD)) ]--> [ (A(B(CD))) ]
- return
[ (AB), (CD) ]--> [ ((AB)(CD)) ]
- return .. ditto..
on return i.e. at final step of each recursion, check if this value smaller than of any other.
Below is JAVA,c# and Javascript implementation of above steps.
C++
#include <algorithm>
#include <climits>
#include <iostream>
#include <string>
using namespace std;
class FinalCost {
public :
string label = "" ;
int cost = INT_MAX;
};
class MatrixMultiplyCost {
public :
void optimalCost( int ** matrices, string* labels,
int prevCost, FinalCost& finalCost,
int len)
{
if (len < 2) {
finalCost.cost = 0;
return ;
}
else if (len == 2) {
int cost = prevCost
+ (matrices[0][0] * matrices[0][1]
* matrices[1][1]);
if (cost < finalCost.cost) {
finalCost.cost = cost;
finalCost.label
= "(" + labels[0] + labels[1] + ")" ;
}
return ;
}
for ( int i = 0; i < len - 1; i++) {
int j;
int ** newMatrix = new int *[len - 1];
string* newLabels = new string[len - 1];
int subIndex = 0;
int cost = (matrices[i][0] * matrices[i][1]
* matrices[i + 1][1]);
for (j = 0; j < i; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
newMatrix[subIndex] = new int [2];
newMatrix[subIndex][0] = matrices[i][0];
newMatrix[subIndex][1] = matrices[i + 1][1];
newLabels[subIndex++]
= "(" + labels[i] + labels[i + 1] + ")" ;
for (j = i + 2; j < len; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
optimalCost(newMatrix, newLabels,
prevCost + cost, finalCost,
len - 1);
}
}
FinalCost findOptionalCost( int * arr, int len)
{
int ** matrices = new int *[len - 1];
string* labels = new string[len- 1];
for ( int i = 0; i < len - 1; i++) {
matrices[i] = new int [2];
matrices[i][0] = arr[i];
matrices[i][1] = arr[i + 1];
labels[i] = char (
65 + i);
}
FinalCost finalCost;
optimalCost(matrices, labels, 0, finalCost,
len - 1);
return finalCost;
}
};
void printMatrix( int ** matrices, int len) {
cout << "matrices = " << endl << "[" ;
for ( int i = 0; i < len; i++) {
cout << "[" << matrices[i][0] << " " << matrices[i][1] << "]" << " " ;
}
cout << "]" << endl;
}
int main() {
MatrixMultiplyCost calc;
int arr[] = {40, 20, 30, 10, 30};
int len = sizeof (arr) / sizeof (arr[0]);
int **matrices = new int *[len - 1];
string *labels = new string[len - 1];
for ( int i = 0; i < len - 1; i++) {
matrices[i] = new int [2];
matrices[i][0] = arr[i];
matrices[i][1] = arr[i + 1];
labels[i] = char (65 + i);
}
printMatrix(matrices, len-1);
FinalCost cost = calc.findOptionalCost(arr, len);
cout << "Final labels: \n" << cost.label << endl;
cout << "Final Cost:\n" << cost.cost << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class MatrixMultiplyCost {
static class FinalCost
{
public String label = "" ;
public int cost = Integer.MAX_VALUE;
}
private void optimalCost( int [][] matrices,
String[] labels, int prevCost,
FinalCost finalCost)
{
int len = matrices.length;
if (len < 2 )
{
finalCost.cost = 0 ;
return ;
}
else if (len == 2 )
{
int cost = prevCost
+ (matrices[ 0 ][ 0 ] *
matrices[ 0 ][ 1 ] *
matrices[ 1 ][ 1 ]);
if (cost < finalCost.cost)
{
finalCost.cost = cost;
finalCost.label
= "(" + labels[ 0 ]
+ labels[ 1 ] + ")" ;
}
return ;
}
for ( int i = 0 ; i < len - 1 ; i++)
{
int j;
int [][] newMatrix = new int [len - 1 ][ 2 ];
String[] newLabels = new String[len - 1 ];
int subIndex = 0 ;
int cost = (matrices[i][ 0 ] * matrices[i][ 1 ]
* matrices[i + 1 ][ 1 ]);
for (j = 0 ; j < i; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
newMatrix[subIndex][ 0 ] = matrices[i][ 0 ];
newMatrix[subIndex][ 1 ] = matrices[i + 1 ][ 1 ];
newLabels[subIndex++]
= "(" + labels[i] + labels[i + 1 ] + ")" ;
for (j = i + 2 ; j < len; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
optimalCost(newMatrix, newLabels,
prevCost + cost, finalCost);
}
}
public FinalCost findOptionalCost( int [] arr)
{
int [][] matrices = new int [arr.length - 1 ][ 2 ];
String[] labels = new String[arr.length - 1 ];
for ( int i = 0 ; i < arr.length - 1 ; i++) {
matrices[i][ 0 ] = arr[i];
matrices[i][ 1 ] = arr[i + 1 ];
labels[i] = Character.toString(( char )( 65 + i));
}
printMatrix(matrices);
FinalCost finalCost = new FinalCost();
optimalCost(matrices, labels, 0 , finalCost);
return finalCost;
}
/**
* Driver Code
*/
public static void main(String[] args)
{
MatrixMultiplyCost calc = new MatrixMultiplyCost();
int [] arr = { 40 , 20 , 30 , 10 , 30 };
FinalCost cost = calc.findOptionalCost(arr);
System.out.println( "Final labels: \n" + cost.label);
System.out.println( "Final Cost:\n" + cost.cost
+ "\n" );
}
/**
* Ignore this method
* - THIS IS for DISPLAY purpose only
*/
private static void printMatrix( int [][] matrices)
{
System.out.print( "matrices = \n[" );
for ( int [] row : matrices) {
System.out.print(Arrays.toString(row) + " " );
}
System.out.println( "]" );
}
}
|
Python3
class FinalCost:
def __init__( self ):
self .label = ""
self .cost = float ( "inf" )
def optimalCost(matrices, labels, prevCost, finalCost):
length = len (matrices)
if length < 2 :
finalCost.cost = 0
elif length = = 2 :
cost = prevCost + matrices[ 0 ][ 0 ] * matrices[ 0 ][ 1 ] * matrices[ 1 ][ 1 ]
if cost < finalCost.cost:
finalCost.cost = cost
finalCost.label = "(" + labels[ 0 ] + labels[ 1 ] + ")"
else :
for i in range (length - 1 ):
newMatrix = [[ 0 ] * 2 for i in range (length - 1 )]
newLabels = [ 0 ] * (length - 1 )
subIndex = 0
cost = matrices[i][ 0 ] * matrices[i][ 1 ] * matrices[i + 1 ][ 1 ]
for j in range (i):
newMatrix[subIndex] = matrices[j]
newLabels[subIndex] = labels[j]
subIndex + = 1
newMatrix[subIndex][ 0 ] = matrices[i][ 0 ];
newMatrix[subIndex][ 1 ] = matrices[i + 1 ][ 1 ];
newLabels[subIndex] = "(" + str (labels[i]) + str (labels[i + 1 ]) + ")" ;
subIndex + = 1
for j in range (i + 2 , length):
newMatrix[subIndex] = matrices[j];
newLabels[subIndex] = labels[j];
subIndex + = 1
optimalCost(newMatrix, newLabels, prevCost + cost, finalCost);
def findOptionalCost(arr):
matrices = [[ 0 ] * 2 for i in range ( len (arr) - 1 )]
labels = [ 0 ] * ( len (arr) - 1 )
for i in range ( len (arr) - 1 ):
matrices[i][ 0 ] = arr[i]
matrices[i][ 1 ] = arr[i + 1 ]
labels[i] = chr ( 65 + i)
print ( "matrices =" , matrices)
finalCost = FinalCost()
optimalCost(matrices, labels, 0 , finalCost)
return finalCost
arr = [ 40 , 20 , 30 , 10 , 30 ]
cost = findOptionalCost(arr)
print ( "Final labels:" + cost.label)
print ( "Final Cost:" + str (cost.cost))
|
C#
using System;
using System.Collections.Generic;
public class Cost
{
public string label = "" ;
public int cost =Int32.MaxValue;
}
public class MatrixMultiplyCost {
private void optimalCost( int [][] matrices,
string [] labels, int prevCost,
Cost Cost)
{
int len = matrices.Length;
if (len < 2)
{
Cost.cost = 0;
return ;
}
else if (len == 2)
{
int cost = prevCost
+ (matrices[0][0] *
matrices[0][1] *
matrices[1][1]);
if (cost < Cost.cost)
{
Cost.cost = cost;
Cost.label
= "(" + labels[0]
+ labels[1] + ")" ;
}
return ;
}
for ( int i = 0; i < len - 1; i++)
{
int j;
int [][] newMatrix = new int [len - 1][];
for ( int x = 0; x < len - 1; x++)
newMatrix[x] = new int [2];
string [] newLabels = new string [len - 1];
int subIndex = 0;
int cost = (matrices[i][0] * matrices[i][1]
* matrices[i + 1][1]);
for (j = 0; j < i; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
newMatrix[subIndex][0] = matrices[i][0];
newMatrix[subIndex][1] = matrices[i + 1][1];
newLabels[subIndex++]
= "(" + labels[i] + labels[i + 1] + ")" ;
for (j = i + 2; j < len; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
optimalCost(newMatrix, newLabels,
prevCost + cost, Cost);
}
}
public Cost findOptionalCost( int [] arr)
{
int [][] matrices = new int [arr.Length - 1][];
string [] labels = new string [arr.Length - 1];
for ( int i = 0; i < arr.Length - 1; i++) {
matrices[i] = new int [2];
matrices[i][0] = arr[i];
matrices[i][1] = arr[i + 1];
labels[i] = Convert.ToString(( char )(65 + i));
}
printMatrix(matrices);
Cost Cost = new Cost();
optimalCost(matrices, labels, 0, Cost);
return Cost;
}
public static void Main( string [] args)
{
MatrixMultiplyCost calc = new MatrixMultiplyCost();
int [] arr = { 40, 20, 30, 10, 30 };
Cost cost = calc.findOptionalCost(arr);
Console.WriteLine( " labels: \n" + cost.label);
Console.WriteLine( " Cost:\n" + cost.cost
+ "\n" );
}
private static void printMatrix( int [][] matrices)
{
Console.Write( "matrices = \n[" );
foreach ( int [] row in matrices) {
Console.Write( "[ " + string .Join( " " , row) + " " + "], " );
}
Console.WriteLine( "]" );
}
}
|
Javascript
class FinalCost {
constructor() {
this .label = "" ;
this .cost = Number.MAX_VALUE;
}
}
function optimalCost(matrices, labels, prevCost, finalCost) {
var len = matrices.length;
if (len < 2) {
finalCost.cost = 0;
return ;
} else if (len == 2) {
var Cost =
prevCost + matrices[0][0] * matrices[0][1] * matrices[1][1];
if (Cost < finalCost.cost) {
finalCost.cost = Cost;
finalCost.label = "(" + labels[0] + labels[1] + ")" ;
}
return ;
}
for ( var i = 0; i < len - 1; i++) {
var j;
let newMatrix = Array.from(Array(len - 1), () => new Array(2));
let newLabels = new Array(len - 1);
subIndex = 0;
Cost = matrices[i][0] * matrices[i][1] * matrices[i + 1][1];
for (j = 0; j < i; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
newMatrix[subIndex][0] = matrices[i][0];
newMatrix[subIndex][1] = matrices[i + 1][1];
newLabels[subIndex++] = "(" + labels[i] + labels[i + 1] + ")" ;
for (j = i + 2; j < len; j++) {
newMatrix[subIndex] = matrices[j];
newLabels[subIndex++] = labels[j];
}
optimalCost(newMatrix, newLabels, prevCost + Cost, finalCost);
}
}
function findOptionalCost(arr) {
let matrices = Array.from(Array(arr.length - 1), () => new Array(2));
let labels = new Array(arr.length - 1);
for ( var i = 0; i < arr.length - 1; i++) {
matrices[i][0] = arr[i];
matrices[i][1] = arr[i + 1];
labels[i] = String.fromCharCode(65 + i);
}
printMatrix(matrices);
let finalCost = new FinalCost();
optimalCost(matrices, labels, 0, finalCost);
return finalCost;
}
var arr = [40, 20, 30, 10, 30];
cost = findOptionalCost(arr);
console.log( "Final labels:" + cost.label);
console.log( "Final Cost:" + cost.cost);
function printMatrix(matrices) {
console.log( "matrices = " );
for ( var k = 0; k < matrices.length; k++) {
console.log(matrices[k]);
}
}
|
Outputmatrices =
[[40 20] [20 30] [30 10] [10 30] ]
Final labels:
((A(BC))D)
Final Cost:
26000
Time Complexity : O(n2)
Auxiliary Space:O(n2)
This article is contributed by Yasin Zafar. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.