zoukankan      html  css  js  c++  java
  • 题解——加分二叉树

    题解——加分二叉树

    关于jmr,他进集训队了(差距过大)
    这道题是一道绿题(码量上),但思路上不乏是道好题。
    Luogu传送门:P1040 加分二叉树

    还是搬运一下题面吧:
    设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtreesubtree(也包含treetree本身)的加分计算方法如下:

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

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

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

    (1)treetree的最高加分

    (2)treetree的前序遍历

    注意: n <= 30

    解题思路:

    这道题有点类似于关于树形DP的转化

    最初看见这个中序遍历还真的无从下手,但我们仔细想想,在中序遍历中,对于任意点 i 作为根节点, [ 1 , i-1 ]必定为其左子树 ,[ i+1 , r ]必为其右子树。 再推广一下,对于一段可能成为子树的区间,我们可以枚举改子树的根节点,然后用dfs返回的值更新最值。
    关于更新:由于代码简单,就写代码中了。

    求前序遍历,我们只需要在枚举出最值的时候记录当前根节点,在跑一遍dfs输出即可。

    AC code:

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int  s = 0 ; 
        char g = getchar() ;
        while( g>'9'||g<'0')g=getchar() ;
        while(g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ;
        return s ;
    }
    const  int  MAXN  = 32 ;
    int root[ MAXN ][ MAXN ] , dp[ MAXN ][ MAXN ] , M , a[ MAXN ] ; //root数组记录根节点 
    int dfs( int l , int  r ){
        if( dp[ l ][ r ] )return dp[ l ][ r ] ; //记忆化
        if( l > r )return 1 ;//边界 返回1
        if( l == r ){  // 叶节点  返回当前叶节点权值
            dp[ l ][ r ] = a[ l ] ;root[ l ][ r ] = l ;
            return dp[ l ][ r ] ; 
        }
        for( register int i = l ; i <= r ; ++i ){ //枚举子树根节点
            int  w = dfs( l , i-1 )*dfs( i+1 ,r )+a[ i ] ;
            if( w > dp[ l ][ r ] )dp[ l ][ r ] = w , root[ l ][ r ] = i ;//updata
        }
        return dp[ l ][ r ] ; 
    }
    void firt_( int l , int r )//先序输出
    {
        if ( l > r )return ;
        printf ( "%d ",root[ l ][ r ] );
        firt_( l , root[ l ][ r ]-1 ) ;
        firt_( root[ l ][ r ] + 1 , r ) ;
    }
    int main(){
        M = read() ;
        for( register int i = 1 ; i <= M ; ++i )a[ i ] = read() ;
        cout<<dfs( 1 , M )<<endl ; 
        firt_( 1 , M ) ;
        return 0 ;
    } 
    
    

    这道题将先序遍历和树上Dp的结合确实ssw02最早没想到

    有疑惑和建议,可以留下评论或私我。

    如果你喜欢我的文章,请点赞支持,谢谢。

  • 相关阅读:
    SpringBoot整合redis
    maven dependency全局排除
    Spring Boot程序接收命令行参数
    MySQL8.0.20安装详解
    ITRS/GCRS/J2000坐标系的相互转换
    SpringBoot日记——日志框架篇
    SpringBoot集成log4j,解决log4j.properties不生效问题
    Office
    git下载
    WINDOWS上KAFKA运行环境安装
  • 原文地址:https://www.cnblogs.com/ssw02/p/11217772.html
Copyright © 2011-2022 走看看