文章目录
- 题目描述
 - 思路分析
 - 实现代码
 - 分析总结
 
题目描述

思路分析


实现代码
- 不过我的代码写的真的不够简洁,逻辑不够清晰,后续多练练吧。
 
// 组合数问题
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 35;
int n,f[N][N],g[N][N],w[N];
// f[i][j]表示区间i到j的构成的二叉树最大的加数
// g[i][j]表示区间i到j的构成最大加数二叉树的根节点的坐标
// w[i]表示第i个节点的权值
void dfs(int l,int r){
    if(l > r) return;
    int k = g[l][r];
    cout<<k<<" ";
    dfs(l,k-1);
    dfs(k + 1,r);
}
int main(){
    cin>>n;
    for(int i = 1;i <= n;i ++) cin>>w[i];
    // 遍历区间的长度
    for (int len = 1; len <= n; ++len) {
        // 遍历区间左端点
        for (int i = 1; i + len - 1 <= n ; ++i) {
            int j = i + len -1;
            // 左右节点相等,不用额外尽心遍历
            if (i == j) f[i][j] = w[i],g[i][j] = i;
            else{
                // 遍历划分节点,总共是三种情况
                for (int k = i; k <= j; ++k) {
                    int score = 0;
                    if (k == i){
                        // 划分节点在左端点,没有左子节点
                        score = w[k] + f[ k + 1][j];
                    }
                    else if (k == j){
                        // 划分节点在右端点,没有右子节点
                        score = w[k] + f[i][k - 1];
                    }
                    else
                    {
                        // 划分节点在中间,左右子节点都有
                        score = w[k] + f[i][k - 1] * f[k + 1][j];
                    }
                    // 记录顶点节点
                    if(f[i][j] < score) {
                        f[i][j] = score;
                        g[i][j] = k;
                    }
                }
            }
        }
    }
    cout<<f[1][n]<<endl;
    dfs(1,n);
};
 
分析总结
- 在这里要知道一些关于前序、后序还有中序转换的问题,既然考到了,但是我一点都想不起来。
 - 思路分析很重要
 



















