• 加分二叉树【树形dp】


    设一个n个节点的二叉树tree的中序遍历为(l, 2, 3, …, n),其中数字 1, 2, 3, …, n为节点编号。每个节点都有一个分数(均为正整数),记第j个节点的分数为,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:

    • subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数
    • 若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

    试求一棵符合中序遍历为1, 2, 3, …, n) 且加分最高的二叉树tree。要求输出;

    1. tree的最高加分
    2. tree的前序遍历

    我们注意到给出的数据是中序遍历,对于中序遍历, 在根的左右两侧,恰好是他的左右两棵子树的序列

    我们只要枚举区间内的根节点即可

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    typedef long long ll;
    using namespace std;
    const int maxn = 50;
    int n, v[maxn], f[maxn][maxn], root[maxn][maxn];
    //root[i][j]表示区间 i - j 内的根节点
    //f[i][j] 表示 i - j 的最大加分
    void print(int l, int r){//前序输出区间[l, r]
        if(l>r) return;
        if(l==r){
            printf("%d ", l);
            return;
        }
        printf("%d ", root[l][r]);
        print(l, root[l][r]-1);
        print(root[l][r]+1, r);
    }
    int main(){
        scanf("%d", &n);
        for(int i=1; i<=n; i++) scanf("%d", &v[i]);//读入分数
        for(int i=1; i<=n; i++) f[i][i] = v[i],f[i][i-1] = 1, root[i][i]=i;//初始化,f[i][i-1]表示空子树
        for(int len=1; len<n; len++){//枚举区间长度
            for(int i=1; i+len<=n; i++){//枚举起点 i
                int j = i+len;        //终点 j
                f[i][j] = f[i + 1][j] + f[i][i];//初始化假设左子树为空
                root[i][j] = i; //从左子树为空开始
                for(int k=i+1; k<j; k++){//枚举区间内根节点
                    if(f[i][j]<f[i][k-1]*f[k+1][j]+f[k][k]){
                        f[i][j] = f[i][k-1]*f[k+1][j]+f[k][k];
                        root[i][j] = k;
                    }
                }
            }
        }
        printf("%d
    ", f[1][n]);
        print(1, n);
        return 0;
    }
  • 相关阅读:
    从零开始学安全(七)●Linux基础命令学习笔记
    从零开始学安全(六)●黑客常用的Dos命令
    ABAP
    ABAP modify screen:修改屏幕,实现隐藏、禁止输入字段
    C#以对象为成员的例子
    C#构造函数、属性的应用
    C#属性方法 构造函数(不知道自己理解的对不对)
    C#斐波那契数列求法(比较阶乘和循环所用时间)
    C#函数的递归
    C#函数的参数传递2(refout)
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12638390.html
Copyright © 2020-2023  润新知