首页 > 其他 > 详细

479. 加分二叉树

时间:2021-04-17 17:30:49      阅读:14      评论:0      收藏:0      [点我收藏+]

题目链接: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

 

479. 加分二叉树

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!