#include using namespace std; const int N = 35; int n; int w[N]; int f[N][N]; int g[N][N]; // 计算最大结果 int dfs(int l, int r) { int &v = f[l][r]; // 简化代码 if (v) return v; // 记忆化搜索 if (l == r) return g[l][r] = l, v = w[l]; // 叶子分数是权值 if (l > r) return v = 1; // 题设空子树的分数为1,递归出口 for (int k = l; k <= r; k++) { // 因为k是枚举根,根占了一个点,所以,左侧是[l,k-1],右侧是[k+1,r] int t = dfs(l, k - 1) * dfs(k + 1, r) + w[k]; if (t > v) v = t, g[l][r] = k; // 记录第一次出现最大值时的k,方便输出字典序 } return v; } // 前序遍历输出路径 void out(int l, int r) { if (l > r) return; // 递归出口 cout << g[l][r] << " "; // 输出最优根 out(l, g[l][r] - 1); // 递归左子树 out(g[l][r] + 1, r); // 递归右子树 } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &w[i]); // 区间1~n的最大结果 cout << dfs(1, n) << endl; // 输出路径 out(1, n); return 0; }