Vanya is doing his maths homework. He has an expression of form , where x1, x2, ..., xn are digits from 1 to 9, and sign represents either a plus '+' or the multiplication sign '*'. Vanya needs to add one pair of brackets in this expression so that to maximize the value of the resulting expression.
Input
The first line contains expression s (1 ≤ |s| ≤ 5001, |s| is odd), its odd positions only contain digits from 1 to 9, and even positions only contain signs + and * .
The number of signs * doesn't exceed 15.
Output
In the first line print the maximum possible value of an expression.
Sample test(s)
Input
3+5*7+8*4
Output
303
Input
2+3*5
Output
25
Input
3*4*5
Output
60
解题思路:动态规划,首先我们枚举区间s->e,计算s->e区间的表达式的值,然后计算s向左乘的最左边的数,e向右乘的最右边的数,然后剩下的便是首尾两端的区间表达式的和,将这三部分加起来取最大值即可,因此本题的核心便是计算表达式区间s->e的表达式的值,利用动态规划来求解。
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <string> #include <vector> #include <deque> #include <queue> #include <stack> #include <map> #include <set> #include <utility> #include <algorithm> #include <functional> using namespace std; typedef long long ll; const int maxn = 5010; char str[maxn]; ll dp[2600][2600]; int dig[maxn]; char op[maxn]; int n1, n2; int main() { //freopen("aa.in", "r", stdin); int n; n1 = n2 = 0; scanf("%s", str); n = strlen(str); for(int i = 0; i < n; ++i) { if(str[i] >= '0' && str[i] <= '9') { dig[n1++] = str[i]-'0'; } else { op[n2++] = str[i]; } } for(int i = 0; i < n1; ++i) { dp[i][i] = dig[i]; } for(int l = 1; l < n1; ++l) { for(int i = 0; i + l < n1; ++i) { int j = i + l; if(op[j-1] == '+') { dp[i][j] = dp[i][j-1] + dig[j]; } else { ll t = dig[j]; int id = j - 1; while(id >= i) { if(op[id] == '*') { t *= dig[id]; id--; } else { break; } } if(id < i) { dp[i][j] = t; } else { dp[i][j] = dp[i][id] + t; } } } } ll ans = dp[0][n1-1]; for(int s = 0; s < n1; ++s) { for(int e = s + 1; e < n1; ++e) { ll t = dp[s][e]; int id1 = s - 1; while(id1 >= 0) { if(op[id1] == '*') { t *= dig[id1]; id1--; } else { break; } } int id2 = e; while(id2 < n1 - 1) { if(op[id2] == '*') { t *= dig[id2+1]; id2++; } else { break; } } if(id1 >= 0) { t += dp[0][id1]; } if(id2 + 1 < n1) { t += dp[id2+1][n1-1]; } ans = max(ans, t); } } cout << ans << endl; return 0; }