牛客 加分二叉树(dp)

因为我们知道中序遍历,所以可以设计dp状态为1-i为一个子树的最大值,这样即可用区间dp或者记忆化搜索来解决。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<functional>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N];
ll f[50][50];
int g[50][50];
int dfs(int l, int r){ 
    if (l == r){
        g[l][r] = l;
        return a[l];
    }
    if (f[l][r] != -1) return f[l][r];
    if (l > r) return 1;
    for(int u=l;u<=r;u++){
        ll tmp=dfs(l,u-1)*1ll*dfs(u+1,r)+a[u];
        if(f[l][r]<tmp){
            g[l][r]=u;
            f[l][r]=tmp;
        }
    }
    return f[l][r];
}
void get(int l,int r){
    if(l>r){
        return ;
    }
    cout<<g[l][r]<<" ";
    get(l,g[l][r]-1);
    get(g[l][r]+1,r);
}
int main(){
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        cin>>a[i];
    }
    memset(f,-1,sizeof f);
    dfs(1,n);
    cout<<f[1][n]<<endl;
    get(1,n);
    cout<<endl;
}
View Code

 

posted @ 2020-05-22 09:35  朝暮不思  阅读(163)  评论(0编辑  收藏  举报