Given a sequence of digits d1, d2, ..., dn and a sequence of binary operators op1, op2, ..., op(n-1) where each operator is in {'+', '-', '*'}, place parentheses to maximize the value of the arithmetic expression:
d1 op1 d2 op2 ... op(n-1) dn
Return the maximum achievable value.
This problem is similar in spirit to (but distinct from) LeetCode’s “Different Ways to Add Parentheses” which asks for all possible results. Here we only need the maximum value.
Input: expression ="5-8+7*4-8+9"Output: 200Explanation: Maximum is achieved by 5-((8+7)*(4-(8+9)))=5-(15*(4-17))=5-(15*-13)=5-(-195)=200.Note: 32(from 5-8+(7*(4-8+9)))is a valid achievable value but not the maximum.
Parenthesization determines the order of operations. Splitting at an operator partitions the expression into a left sub-expression and a right sub-expression.
Because subtraction and multiplication with negatives can flip sign, to compute the maximum for a range E(i, j) we need BOTH the minimum and maximum values of its left and right sub-ranges. Combining extremes (min/min, min/max, max/min, max/max) covers all possibilities.
This mirrors matrix-chain or boolean parenthesization DP: store best (max) and worst (min) results for every interval and build up by increasing length.
M(i,j) = maximum of sub-expression E(i,j); m(i,j) = minimum of E(i,j).
We denote by M(i,j) as the maximum value of the sub-expression spanning numbers ( i..j) (inclusive) and by m(i,j) its minimum. For any split position k with operator op_k between numbers k and k+1:
We compute subproblems in order of increasing length (j - i) ensuring dependencies ((i,k) and (k+1,j)) are ready:
defmin_and_max(i, j):
min_val =+inf
max_val =-inf
for k in range(i, j):
op = ops[k]
a = M[i][k] op M[k+1][j]
b = M[i][k] op m[k+1][j]
c = m[i][k] op M[k+1][j]
d = m[i][k] op m[k+1][j]
min_val = min(min_val, a, b, c, d)
max_val = max(max_val, a, b, c, d)
return min_val, max_val
defmaximize_expression(nums, ops):
n = len(nums)
for i in range(n):
M[i][i] = nums[i]
m[i][i] = nums[i]
for L in range(2, n+1):
for i in range(0, n-L+1):
j = i + L -1 m[i][j], M[i][j] = min_and_max(i, j)
return M[0][n-1]
#include<vector>#include<string>#include<cctype>#include<limits>#include<algorithm>usingnamespace std;
classSolution {
longapply(long a, long b, char op) {
if (op =='+') return a + b;
if (op =='-') return a - b;
return a * b; // '*'
}
public:long maximizeExpression(const string &expr) {
vector<long> nums; vector<char> ops;
for (size_t i =0; i < expr.size();) {
if (isdigit(expr[i])) {
long val =0;
while (i < expr.size() && isdigit(expr[i])) {
val = val *10+ (expr[i]-'0');
++i;
}
nums.push_back(val);
} elseif (expr[i] =='+'|| expr[i] =='-'|| expr[i] =='*') {
ops.push_back(expr[i]);
++i;
} else {
++i; // ignore spaces or others
}
}
int n = (int)nums.size();
if (n ==0) return0;
vector<vector<long>> mn(n, vector<long>(n, 0));
vector<vector<long>> mx(n, vector<long>(n, 0));
for (int i =0; i < n; ++i) mn[i][i] = mx[i][i] = nums[i];
for (int L =2; L <= n; ++L) {
for (int i =0; i + L -1< n; ++i) {
int j = i + L -1;
long curMin = numeric_limits<long>::max();
long curMax = numeric_limits<long>::min();
for (int k = i; k < j; ++k) {
char op = ops[k];
long a = apply(mx[i][k], mx[k+1][j], op);
long b = apply(mx[i][k], mn[k+1][j], op);
long c = apply(mn[i][k], mx[k+1][j], op);
long d = apply(mn[i][k], mn[k+1][j], op);
curMin = min({curMin, a, b, c, d});
curMax = max({curMax, a, b, c, d});
}
mn[i][j] = curMin; mx[i][j] = curMax;
}
}
return mx[0][n-1];
}
};
import java.util.*;
classSolution {
publiclongmaximizeExpression(String expr) {
List<Long> nums =new ArrayList<>();
List<Character> ops =new ArrayList<>();
for (int i = 0; i < expr.length();) {
char c = expr.charAt(i);
if (Character.isDigit(c)) {
long val = 0;
while (i < expr.length() && Character.isDigit(expr.charAt(i))) {
val = val * 10 + (expr.charAt(i) -'0');
i++;
}
nums.add(val);
} elseif (c =='+'|| c =='-'|| c =='*') {
ops.add(c); i++;
} else {
i++; // skip spaces }
}
int n = nums.size();
if (n == 0) return 0L;
long[][] mn =newlong[n][n];
long[][] mx =newlong[n][n];
for (int i = 0; i < n; i++) mn[i][i]= mx[i][i]= nums.get(i);
for (int L = 2; L <= n; L++) {
for (int i = 0; i + L - 1 < n; i++) {
int j = i + L - 1;
long curMin = Long.MAX_VALUE;
long curMax = Long.MIN_VALUE;
for (int k = i; k < j; k++) {
char op = ops.get(k);
long a = apply(mx[i][k], mx[k+1][j], op);
long b = apply(mx[i][k], mn[k+1][j], op);
long c = apply(mn[i][k], mx[k+1][j], op);
long d = apply(mn[i][k], mn[k+1][j], op);
curMin = Math.min(Math.min(Math.min(curMin, a), Math.min(b, c)), d);
curMax = Math.max(Math.max(Math.max(curMax, a), Math.max(b, c)), d);
}
mn[i][j]= curMin; mx[i][j]= curMax;
}
}
return mx[0][n-1];
}
privatelongapply(long a, long b, char op) {
if (op =='+') return a + b;
if (op =='-') return a - b;
return a * b;
}
}
from typing import List, Tuple
classSolution:
defmaximizeExpression(self, expr: str) -> int:
nums: List[int] = []
ops: List[str] = []
i =0while i < len(expr):
c = expr[i]
if c.isdigit():
val =0while i < len(expr) and expr[i].isdigit():
val = val *10+ int(expr[i])
i +=1 nums.append(val)
elif c in'+-*':
ops.append(c)
i +=1else:
i +=1# skip spaces / others n = len(nums)
if n ==0:
return0 min_dp = [[0]*n for _ in range(n)]
max_dp = [[0]*n for _ in range(n)]
for i in range(n):
min_dp[i][i] = max_dp[i][i] = nums[i]
defapply(a: int, b: int, op: str) -> int:
if op =='+':
return a + b
if op =='-':
return a - b
return a * b
for L in range(2, n+1):
for i in range(0, n-L+1):
j = i + L -1 cur_min =10**18 cur_max =-10**18for k in range(i, j):
op = ops[k]
a = apply(max_dp[i][k], max_dp[k+1][j], op)
b = apply(max_dp[i][k], min_dp[k+1][j], op)
c = apply(min_dp[i][k], max_dp[k+1][j], op)
d = apply(min_dp[i][k], min_dp[k+1][j], op)
cur_min = min(cur_min, a, b, c, d)
cur_max = max(cur_max, a, b, c, d)
min_dp[i][j] = cur_min
max_dp[i][j] = cur_max
return max_dp[0][n-1]