加分二叉树

前序遍历  根左右

中序遍历 左根右

后序遍历 左右根

然后中序遍历有一个很好的区间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 } 

 

posted @ 2018-08-31 14:46  lcan  阅读(152)  评论(0编辑  收藏  举报