$Luogu$ $P1040$ 加分二叉树

链接

背景

\(CCF\) \(NOIP2003\) \(T3\)\(Luogu\) \(P1040\)

题意

设一棵二叉树(形态未知)的中序遍历是 \(\{ 1,2,3,\cdots,n \}\) 。给定这 \(n\) 个节点的权值,规定一棵子树的得分是左右子树得分之积加上根节点权值的结果。请构造出一棵满足题意的树使得得分最大,并求出最大得分和树的先序遍历。注意叶节点的得分是本身权值,仅有一棵子树的节点另一棵空子树得分记为 \(1\)

解法

不是树形 \(dp\) 模板。是习题。
然而我死活想不出解。后来发现我把中序遍历和先序遍历搞混淆了。
由于构造出来的树要满足中序遍历的要求,则选定 \(x\) 点为子树 \([l,r]\) 的根之后左子树只能为 \([l,x-1]\) ,右子树只能为 \([x+1,r]\) 。于是就有了最优子结构性质。
\(f_{l,r}\) 表示中序遍历是 \(\{ l,l+1,l+2,\cdots,r \}\) 的子树的最大得分。则转移应当枚举其中的一个点作为这棵子树的根,再递归计算左右子树的值。
于是考虑记忆化搜索(本质是动态规划的递归实现形式),状态转移是 \(f_{l,r}=\max_\limits{k \in [l,r]} \{ f_{l,k-1} \times f_{k+1,r}+val_k \}\) 。要求的就是 \(f_{l,r}\)
最后考虑怎么输出先序遍历。由于先根、后左子、最后右子,于是在 \(dp\) 的时候可以给每棵子树 \([l,r]\) 确定一个根节点 \(root_{l,r}\) ,做完之后从 \([1,n]\) 开始递归输出即可,先输出根节点,再递归左子树,最后递归右子树。

细节

\(1.\) 两个边界:子树为空(即 \(l>r\) )时显然得分只能为 \(0\) ;子树仅有一个节点(即 \(l=r\) ,是一个叶节点)时显然得分就是本身权值。

\(2.\) 注意输出时为了避免递归不停止,在子树为空(即 \(l>r\) )时直接 \(return\)

\(View\) \(Code\)

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int ret=0,f=1;
    char ch=getchar();
    while('9'<ch||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while('0'<=ch&&ch<='9')
    {
        ret=(ret<<1)+(ret<<3)+ch-'0';
        ch=getchar();
    }
    return ret*f;
}
int n,val[35],rt[35][35];
long long f[35][35];
int dp(int l,int r)
{
    if(r<l)
        return 1;
    if(l==r)
    {
        rt[l][r]=l;
        return val[l];
    }
    if(f[l][r])
        return f[l][r];
    int anspos=0;
    long long ans=0,nowans=0;
    for(register int i=l;i<=r;i++)
    {
        nowans=dp(l,i-1)*dp(i+1,r)+val[i];
        if(nowans>ans)
        {
            ans=nowans;
            anspos=i;
        }
    }
    rt[l][r]=anspos;
    return f[l][r]=ans;
}
void print(int l,int r)
{
    if(r<l)
        return;
    printf("%d ",rt[l][r]);
    print(l,rt[l][r]-1);
    print(rt[l][r]+1,r);
}
int main()
{
    n=read();
    for(register int i=1;i<=n;i++)
        val[i]=read();
    printf("%d\n",dp(1,n));
    print(1,n);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Peter0701/p/11838643.html