1.把子树看作区间
2.枚举根
3.小区间转移到大区间,注意边界
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 50;
long long ans;
int f[MAXN][MAXN];
int bre[MAXN][MAXN], size;
int n,a[MAXN];
void solve(int l, int r) {
if(l>r)
return;
cout << bre[l][r] << " ";
solve(l,bre[l][r]-1);
solve(bre[l][r]+1,r);
}
int main() {
cin >> n;
for(int i=1; i<=n; i++) {
cin >> a[i];
}
for(int i=1; i<=n; i++) {
f[i][i] = a[i];
bre[i][i] = i;
f[i][i-1] = 1;
}
for(int r=1; r<=n; r++) {
for(int l=1; l<=n-r; l++) {
for(int k=l; k<l+r; k++) {
if(f[l][k-1] * f[k+1][l+r] + a[k] > f[l][l+r]) {
f[l][l+r] = f[l][k-1] * f[k+1][l+r] + a[k];
bre[l][l+r] = k;
}
}
}
}
cout << f[1][n] << endl;
solve(1,n);
return 0;
}