You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

46 lines
1.2 KiB

2 years ago
#include <bits/stdc++.h>
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;
}