P1040 加分二叉树

Posted ukcxrtjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1040 加分二叉树相关的知识,希望对你有一定的参考价值。

题面:https://www.luogu.org/problemnew/show/P1040

本题即一个在树上做的区间dp,只不过中间枚举的断点k即为当前dp到的树的根节点,然后将当前区间分为两段,即为树上的左子树和右子树,不过要注意这里的k可以取到端点值,即k的取值范围为[i,j]因为一棵树的左右子树可以为空,接着用dp方程f[i][j]=max(f[i][j],f[i][k-1]*f[k+1][j]+f[k][k])就能求解,那么前序遍历也就自然很好解决了。

Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
const int N=35;
int n,front[N][N];
long long f[N][N];
void printf_front(int l,int r)
    if(l>r)
        return;
    
    printf("%d ",front[l][r]);
    if(l==r)
        return;
    
    printf_front(l, front[l][r]-1);
    printf_front(front[l][r]+1,r);

int main() 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld", &f[i][i]);
        f[i][i-1]=1;
        f[i][i+1]=1;
        front[i][i]=i;
    
    for(int len=1;len<n;len++)
        for(int i=1;i+len<=n;i++)
            int j=i+len;
            for(int k=i;k<=j;k++)
                if(f[i][j]<f[i][k-1]*f[k+1][j]+f[k][k])
                    f[i][j]=f[i][k-1]*f[k+1][j]+f[k][k];
                    front[i][j]=k;
                
            
        
    
    printf("%lld\n",f[1][n]);
    printf_front(1,n);
    return 0;

以上是关于P1040 加分二叉树的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1040 加分二叉树

洛谷P1040 加分二叉树

P1040 加分二叉树

P1040 加分二叉树

洛谷 P1040 加分二叉树

洛谷 P1040 加分二叉树