题目:

 


 

 加分二叉树
【问题描述】
    设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第 i个节点的分数为ditree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
    subtree
的左子树的加分× subtree的右子树的加分+subtree的根的分数
   
若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。
   
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;
   
1tree的最高加分
   
2tree的前序遍历

【输入格式】
   
1行:一个整数nn30),为节点个数。
   
2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。

【输出格式】
   
1行:一个整数,为最高加分(结果不会超过4,000,000,000)。
   
2行:n个用空格隔开的整数,为该树的前序遍历。

【输入样例】
    5
    5 7 1 2 10

【输出样例】
    145
      3 1 2 4 5


 

分析:

 这道题很久以前做过,今天整理树形dp的时候又看到,不同的是他要求输出最大加分树的前序遍历,当时那道题貌似只要求输出最大加分。这也是一个难点,要注意方法。

①按当时的方法做,指标d[l, root, r]表示在中序区间[l, r]里定根root的最大加分。 转移方程:d[i, k, j] = max{d[i]d[m]d[k-1] | m=[i, k)}*max{d[k+1]d[m]d[j] | m=(k, j] }. 抽风般的用了三维指标,有点受二分的影响。解:for i=[0, n)  max{dp(0, i, n-1)}.

②指标:d[l, r]表示在中序区间[l, r]里,可以取到的最大加分。转移方程:d[i, j] = max{d[i, k-1]*d[k+1, j]+a[k] | k=[i, j] }.停止条件:i>j,d[i, j] = 0; i=j,d[i, j] = a[i]; 解: dp(0, n-1).

明显地,第二个看着比较爽。为什么会造成这种二维和三维的差别呢? 看出,其实第二种指标的“动态”程度高些。说实话我还没能完全理解。启示就是,要大胆定动态程度高的指标。

最大加分的前序遍历 借助一个树组g,g[I, r]表示 在中序区间[l, r]里 取得最大加分时的根结点的编号。
      g[I, r]=k
(满足d[I,k-1] * d[k+1,j]+a[k]=d[I,j])。其实就是d[I, r]取最大值时k的值。然后就能方便地递归构造最优解。