题解 P1040 【加分二叉树】

本文详细介绍了一种求解最大权值生成树的算法,通过枚举所有结点作为根结点并使用记忆化搜索来避免重复计算,最终实现以前序遍历方式输出结点。代码示例使用C++实现,包含核心的DFS函数和先序输出函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

以中序遍历的方式输入结点上的值,由于我们需要以前序遍历的方式输出结点,
所以我们必须要知道根结点
我们要确定最大根结点就必须求出最大权值树,我们枚举所有结点作为根结点
如果根结点的编号为x,那么左子树的结点有1~x-1,右子树 结点有x+1~n
 

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=35;
int tree[N];  //用于存储结点的值 
int value[N][N]; //用于存储最大权值和
int root[N][N];  //存储根结点

int dfs(int l,int r)
{
    if(l>r)     //空子树,规定其加分为1
        return 1;
    if(l==r)   //叶子结点,直接返回该结点的值,且将其记录为根 
    {
        root[l][r]=l;
        return tree[l]; 
    } 
    /*  在每一次搜索的开始,如果已经做过,直接调用答案,回溯 */
    if(value[l][r]) //记忆化搜索 防止重复计算
        return value[l][r];

//  int ans=0,flag;
    for(int i=l;i<=r;i++)   //枚举子层次根结点 
    {
        int sum=dfs(l,i-1)*dfs(i+1,r)+tree[i];
        if(sum>value[l][r])
        {
            value[l][r]=sum;    //最大权值和 
            root[l][r]=i;       //保存根结点,最优的根结点  
        }
    }   
//  root[l][r]=flag;   //记忆根结点 
    return  value[l][r];    //记忆化       
}

//如果根结点的编号为x,那么左子树的结点有1~x-1,右子树 结点有x+1~n
//先序输出函数 
void show(int l,int r)
{
    if(l>r) return ;
    cout<<root[l][r]<<' ';
    show(l,root[l][r]-1);   
    show(root[l][r]+1,r);
} 

int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    cin>>n;//输入节点个数
    for(int i=1;i<=n;i++)
        cin>>tree[i];//输入每个节点的分数
    cout<<dfs(1,n)<<endl;   //进入记忆化搜索部分
    show(1,n);//输出函数部分
    return 0;//程序结束     
} 

核心代码:

for(int i=l;i<=r;i++)   //枚举子层次根结点 
{
    int sum=dfs(l,i-1)*dfs(i+1,r)+tree[i];
    if(sum>value[l][r])
    {
        value[l][r]=sum;    //最大权值和 
        root[l][r]=i;       //保存根结点,最优的根结点  
    }
}

特别注意:

if(value[l][r]) //记忆化搜索 防止重复计算                
    return value[l][r];     

 

这是记忆化搜索能快速返回已经查询到的结果的关键

转载于:https://www.cnblogs.com/Sworddust/p/11427842.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值