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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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