#include<iostream> #include<vector> #include<algorithm> using namespace std; //递归 //int Func(vector<int>& arr, int L, int R) { // //此时只有一个气球,直接打爆 // if (L == R) { // return arr[L - 1] * arr[L] * arr[R + 1]; // } // //如过arr[L]或者arr[R] 是最后打爆的 // int Max = max(arr[L - 1] * arr[L] * arr[R + 1] + Func(arr, L + 1, R), // arr[L - 1] * arr[R] * arr[R + 1] + Func(arr, L, R - 1)); // //尝试每一中间位置最后被打爆 // for (int i = L + 1; i < R; ++i) { // Max = max(Max, arr[L - 1] * arr[i] * arr[R + 1] + Func(arr, L, i - 1) + // Func(arr, i + 1, R)); // } // return Max; //} int main() { int n; while (cin >> n) { vector<int> arr(n); for (int i = 0; i < n; ++i) { cin >> arr[i]; } vector<int> v(n + 2); v[0] = 1; v[n + 1] = 1; for (int i = 0; i < n; ++i) { v[i + 1] = arr[i]; } //动态规划 //根据递归的终止条件确定初始值 vector<vector<int>> dp(n + 2,vector<int>(n + 2)); for (int i = 1; i <= n; ++i) { dp[i][i] = v[i - 1] * v[i] * v[i + 1]; } //根据递归式可以看出,当前的dp值只与左边和下边有关,所以自底向上更新 for (int L = n; L >= 1; --L) { for (int R = L + 1; R <= n; ++R) { //最后打爆v[L]的分数 int final_L = v[L - 1] * v[L] * v[R + 1] + dp[L + 1][R]; //最后打爆v[R]的分数 int final_R = v[L - 1] * v[R] * v[R + 1] + dp[L][R - 1]; dp[L][R] = max(final_L,final_R); //尝试最后打中间 for (int k = L + 1; k < R; ++k) { dp[L][R] = max(dp[L][R],v[L - 1] * v[k] * v[R + 1] + dp[L][k - 1] + dp[k + 1][R]); } } } cout << dp[1][n] << endl; } return 0; }