加分二叉树-DP
题目来源:Acwing 479-加分二叉树&NEFU OJ-353 加分二叉树
NEFU OJ题源为多组输入,代码为此oj ac代码
题目描述
设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号。
每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
subtree的左子树的加分 × subtree的右子树的加分 + subtree的根的分数
若某个子树为空,规定其加分为1。叶子的加分就是叶节点本身的分数,不考虑它的空子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。
要求输出:
(1)tree的最高加分
(2)tree的前序遍历
输入描述
第1行:一个整数n,为节点个数(n<30) 。
第2行:n个用空格隔开的整数,为每个节点的分数(0<分数<100)。
输出描述
第1行:一个整数,为最高加分(结果不会超过int范围)。
第2行:n个用空格隔开的整数,为该树的前序遍历。如果存在多种方案,则输出字典序最小的方案。
输入样例
5
5 7 1 2 10
输出样例
145
3 1 2 4 5
OP
y总yyds
思路
首先明确分数计算方式,对于一般的树而言,分数=左树*右树+根分数
如果左树或右树为空,且不均为空,则空树分数视为1;
若左右数均空,则空树分数均视为0,此时分数则仅为根分数。
这道题采用从叶子向根的DP过程,建立 d[ i ][ j ] 表示 [ i , j ] 区间内所有元素构成分数最大的数的分数值。限定该区间的长度,在 [ 1 , n ] 区间从短到长进行DP。
具体的DP过程:
在区间长度为len,左端点 i ,右端点 j = i + len - 1 时,以 k 为区间树的根,d[ i ] [ j ] = max( d[ i ][ k - 1 ] * d[ k + 1 ][ j ] + a[ k ] )。
接下来进行特判:
如果len==1,即 i == j 时,左右子树均为空,d[ i ][ j ] = a[ i ];
如果 k == i,即仅左子树为空,左子树分值为 1;
如果 k == j,仅右子树为空同理。
接下来处理输出要求:
因为要求是前序遍历,故遍历 k 时从左到右即可满足条件,即所有可行解中最小 k。并记录区间树的根节点,输出时按根节点分为两树分别递归即可。
代码
1 |
|
ED
\