前序遍历 根左右
中序遍历 左根右
后序遍历 左右根
然后中序遍历有一个很好的区间DP的性质......
至于前序就是写法了......
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=37; 6 ll ans; 7 int n,node,top; 8 int val[maxn],sta[maxn],midl[maxn][maxn]; 9 ll f[maxn][maxn]; 10 void search(int l,int r){ 11 if(l>r) return; 12 if(l==r){ 13 sta[++top]=l;return; 14 } 15 sta[++top]=midl[l][r]; 16 search(l,midl[l][r]-1); 17 search(midl[l][r]+1,r); 18 } 19 int main(){ 20 cin>>n; 21 for(int i=1;i<=n;i++) cin>>val[i]; 22 for(int len=1;len<=n;len++){ 23 for(int i=1;i<=n;i++){ 24 int j=i+len-1;if(j>n) continue; 25 for(int k=i;k<=j;k++){ 26 if(k==i){ 27 if(f[i][j]<f[k+1][j]+val[k]){ 28 f[i][j]=f[k+1][j]+val[k];midl[i][j]=k; 29 } 30 continue; 31 } 32 if(k==j){ 33 if(f[i][j]<f[i][k-1]+val[k]){ 34 f[i][j]=f[i][k-1]+val[k];midl[i][j]=k; 35 } 36 } 37 else{ 38 if(f[i][j]<f[i][k-1]*f[k+1][j]+val[k]){ 39 f[i][j]=f[i][k-1]*f[k+1][j]+val[k]; 40 midl[i][j]=k; 41 } 42 } 43 if(len==n){ 44 if(f[i][j]>ans){ 45 ans=f[i][j];node=k; 46 } 47 } 48 } 49 } 50 } 51 cout<<ans<<endl; 52 search(1,n); 53 for(int i=1;i<=top;i++) cout<<sta[i]<<" "; 54 cout<<endl; 55 return 0; 56 }