---
# System prepended metadata

title: 'Problem: Maximum Expression by Adding Parentheses'

---

# Problem:
Given a list of integers seperated by + and - , place parentheses in different ways to get the maximum value.


# Solution:

algorithm descripition


```
# I want to find the maximum possible value by adding parentheses
# I’ll use dynamic programming similar to Matrix Chain Multiplication

def maxExpression(nums, ops):
    n = len(nums)
    
    # I’ll make two DP tables: one for max values and one for min values
    maxVal = [[0] * n for _ in range(n)]
    minVal = [[0] * n for _ in range(n)]
    
    # Base case: a single number by itself
    for i in range(n):
        maxVal[i][i] = nums[i]
        minVal[i][i] = nums[i]
    
    # Now I’ll expand the chain length from 2 up to n
    for L in range(2, n + 1):
        for i in range(n - L + 1):
            j = i + L - 1
            maxVal[i][j] = float('-inf')
            minVal[i][j] = float('inf')
            
            # I’ll try every split point k between i and j
            for k in range(i, j):
                op = ops[k]
                
                # compute all combinations for + or -
                if op == '+':
                    a = maxVal[i][k] + maxVal[k + 1][j]
                    b = minVal[i][k] + minVal[k + 1][j]
                else:  # op == '-'
                    a = maxVal[i][k] - minVal[k + 1][j]
                    b = minVal[i][k] - maxVal[k + 1][j]
                
                # I’ll store the best (max and min) outcomes
                maxVal[i][j] = max(maxVal[i][j], a, b)
                minVal[i][j] = min(minVal[i][j], a, b)
    
    # The final maximum value for the whole expression
    return maxVal[0][n - 1]


```

# correctness proof

I use optimal substructures such that:
* any of the lower expressions E[i..j] can be split at k where + or - is called.
* the maximum value E[i..j] depends on the values to the left and the right lower expressions
* Since + and - and associative, this recursive decomp. correctly covers all valid parentheses.

I also used overlapping subproblems
* lower expressions E[i..j] pop up multiple times in different recursive calls. The DP table stores and reuse results so it's only solved once (helps a TON with efficient)

Therefore this dymanmic programming approach ensures a efficient (maybe not optimal) solution.


# time complexity
**Time**
Each Subproblem (i,k) considers all split points k between them. since there are O(n^2) subproblems and each subproblem does O(n) splits...
The total sadly ends up being **O(n^3)**