479. 加分二叉树

时间:2021-04-17
本文章向大家介绍479. 加分二叉树,主要包括479. 加分二叉树使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:https://www.acwing.com/problem/content/481/

思路:因为在中序遍历中,每一棵子树在序列中是连续的一段

所以可以考虑区间dp来计算1~n的合并顺序 dp[i][j] 代表从i~j的一棵二叉树的最大值

然后以根节点k来作为划分子集的依据 每次可以用左子树×右子树 来更新 记得特判边界的问题

因为要输出方案 所以 用g[i][j] 代表i~j这一段的根节点是谁 然后先序递归的时候 输出根节点即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e2+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,int>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 
12 int dp[maxn][maxn];
13 int w[maxn];
14 int g[maxn][maxn];
15 
16 
17 void dfs(int l,int r)
18 {
19     int rt=g[l][r];
20     cout<<rt<<" ";
21     if(l<rt) dfs(l,rt-1);
22     if(r>rt) dfs(rt+1,r);
23 }
24 
25 
26 int main()
27 {
28     ios::sync_with_stdio(false);
29     cin.tie(0);
30     int n;
31     cin>>n;
32     for(int i=1;i<=n;i++) cin>>w[i];
33     for(int len=1;len<=n;len++)
34     {
35         for(int i=1;i+len-1<=n;i++)
36         {
37             int j=i+len-1;
38             if(len==1) dp[i][j]=w[i],g[i][j]=i;
39             else
40             {
41                 for(int k=i;k<=j;k++)
42                 {
43                     int l=k==i?1:dp[i][k-1];
44                     int r=k==j?1:dp[k+1][j];
45 
46                     int tmp=l*r+w[k];
47                     if(tmp>dp[i][j])
48                     {
49                         dp[i][j]=tmp;
50                         g[i][j]=k;
51                     }
52                 }
53             }
54         }
55     }
56     cout<<dp[1][n]<<'\n';
57     dfs(1,n);
58 
59 
60 
61 
62 
63 
64 
65 }
View Code

原文地址:https://www.cnblogs.com/winfor/p/14670949.html