zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Server Application Unavailable 解决办法 (转)
    SQL SERVER:分割函数 split
    Win32汇编_基础
    Win32汇编_异常_筛选器
    创建进程常用函数
    内存常用函数
    桃花庵歌
    文天祥的诗
    Socket I/O模型全接触
    函数指针的神奇
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9650821.html
Copyright © 2011-2022 走看看