#include<bits/stdc++.h>
using namespace std;
int n;
int a[40],root[40][40];
long long dp[40][40];
long long dfs(int L,int R) {
if(L>R) return 1;//找完
if(dp[L][R]) return dp[L][R];//有了直接返回
long long maxn=0;
for(int i=L; i<=R; i++) {
long long t=dfs(L,i-1) * dfs(i+1,R)+a[i];/*
subtree 的左子树的加分乘subtree的右子树的加分+ subtree 的根的分数。
*/
if(t>maxn) {//记录最高分和此时的点
maxn=t;
root[L][R]=i;
}
}
return dp[L][R]=maxn;//搜完返回并记录最大
}
void dg(int L,int R) {//前序遍历
if(L>R) return;
printf("%d ",root[L][R]);
dg(L,root[L][R]-1);
dg(root[L][R]+1,R);
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
cin>>a[i];
dp[i][i]=a[i];//记录单结点数
root[i][i]=i;//标记
}
printf("%lld\n",dfs(1,n));
dg(1,n);
return 0;
}前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子数。
版权声明:本文为qq_62674859原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。