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.
|
|
|
|
#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;
|
|
|
|
|
}
|