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. Print the optimal parenthesization (bracketing) of the matrix chain multiplication.
Matrix multiplication is associative, so the order of multiplication can be changed by parenthesizing the product differently. The goal is to minimize the total number of scalar multiplications. We use dynamic programming to compute the minimum cost and store the split points to reconstruct the optimal parenthesization.
classSolution:
defmatrixChainOrder(self, arr):
n = len(arr)
dp = [[0]*n for _ in range(n)]
bracket = [[0]*n for _ in range(n)]
for l in range(2, n):
for i in range(1, n-l+1):
j = i + l -1 dp[i][j] = float('inf')
for k in range(i, j):
q = dp[i][k] + dp[k+1][j] + arr[i-1]*arr[k]*arr[j]
if q < dp[i][j]:
dp[i][j] = q
bracket[i][j] = k
defprintParenthesis(i, j, name):
if i == j:
res = name[0]
name[0] = chr(ord(name[0]) +1)
return res
res ="(" res += printParenthesis(i, bracket[i][j], name)
res += printParenthesis(bracket[i][j]+1, j, name)
res +=")"return res
name = ['A']
return printParenthesis(1, n-1, name)
# Example usage:# arr = [40, 20, 30, 10, 30]# sol = Solution()# print(sol.matrixChainOrder(arr))