• luogu1040 加分二叉树


    题目大意

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

    subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数

    若某个子树为主,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

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

    1tree的最高加分

    2tree的前序遍历

    题解

      本题最容易忽略的性质便是二叉树中的每一个子树的中序遍历都是一段连续的区间。所以对于一段区间,根据选区间中哪个点作为根来分类动规即可。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdarg>
    using namespace std;
    
    void _printf(char *format, ...)
    {
    #ifdef _DEBUG
        va_list(args);
        va_start(args, format);
        vprintf(format, args);
        va_end(args);
    #endif
    }
    //-------------------------------------------------------------------------
    const int MAX_NODE = 35;
    long long F[MAX_NODE][MAX_NODE];
    int RootId[MAX_NODE][MAX_NODE], Val[MAX_NODE];
    int TotNode;
    
    void DP()
    {
        for (int i = 1; i <= TotNode; i++)
        F[i][i - 1] = F[i][i + 1] = 1;
        for (int i = 1; i <= TotNode; i++)
        {
        F[i][i] = Val[i];
        RootId[i][i] = i;
        }
        for (int len = 2; len <= TotNode; len++)
        for (int i = 1; i <= TotNode - len + 1; i++)
        {
            int j = i + len - 1;
            for (int k = i; k <= j; k++)
            {
            if (F[i][k - 1] * F[k + 1][j] + Val[k] > F[i][j])
            {
                F[i][j] = F[i][k - 1] * F[k + 1][j] + Val[k];
                RootId[i][j] = k;
            }
            }
        }
    }
    
    void Print(int l, int r)
    {
        if (l > r)
        return;
        printf("%d ", RootId[l][r]);
        Print(l, RootId[l][r] - 1);
        Print(RootId[l][r] + 1, r);
    }
    
    int main()
    {
    #ifdef _DEBUG
        freopen("c:\noi\source\input.txt", "r", stdin);
    #endif
        scanf("%d", &TotNode);
        for (int i = 1; i <= TotNode; i++)
        scanf("%d", Val + i);
        DP();
        printf("%lld
    ", F[1][TotNode]);
        Print(1, TotNode);
        return 0;
    }
    

      

  • 相关阅读:
    OLT配置学习
    notepad配合正则表达式处理文本
    利用expect和sshpass完美非交互性执行远端命令
    yum 数据库报错与重构
    杀死dialog
    OLT配置说明
    freeradius下发限速信息字段
    debug调试日志和数据查询
    通过windows的超级终端连接华为交换机
    强制清除交换机端口所有配置
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9650821.html
Copyright © 2020-2023  润新知