https://www.luogu.org/problemnew/show/P1040#sub

题目描述

设一个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个用空格隔开的整数,为每个节点的分数(分数<100)。

输出格式:

第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。

第2行:n个用空格隔开的整数,为该树的前序遍历。

输入输出样例

输入样例#1:

5
5 7 1 2 10

输出样例#1:

145
3 1 2 4 5

解题思路(某学长讲过的题,印象深刻)

    (1)区间DP:树的中序遍历是有序的,左儿子右儿子很明确。树在遍历中是一段连续区间,满足局部最优->全局最优。

(2)树的先序遍历输出:记录每一段的根即可。

代码

#include<iostream>
using namespace std;
long long n,f[][],a,b,root[][];
void dfs(int l,int r){//先序遍历输出
if(l>r) return;
if(l==r){
cout<<root[l][r]<<' ';
return;
}
cout<<root[l][r]<<' ';
dfs(l,root[l][r]-);
dfs(root[l][r]+,r);
}
int main(){
cin>>n;//节点数
for(int i=;i<=n;i++)
cin>>f[i][i],root[i][i]=i,f[i][i-]=;//预处理根,DP数组,因为相乘,所有边界设为1
for(int i=n;i>=;i--)//枚举起点
for(int j=i+;j<=n;j++)//枚举终点
for(int k=i;k<=j;k++){//枚举根
a=f[i][k-]*f[k+][j]+f[k][k],b=f[i][j];
if(a>b) f[i][j]=a,root[i][j]=k;
if(a==b&&root[i][j]>k) root[i][j]=k;
}
cout<<f[][n]<<endl;
dfs(,n);
return ;
}

欢迎指正评论O(∩_∩)O~~

  

【区间DP】加分二叉树的更多相关文章

  1. [树形DP]加分二叉树

    加 分 二 叉 树 加分二叉树 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第j ...

  2. [Swust OJ 360]--加分二叉树(区间dp)

    题目链接:http://acm.swust.edu.cn/problem/360/ Time limit(ms): 1000 Memory limit(kb): 65535   Description ...

  3. P1040 加分二叉树 区间dp

    题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...

  4. 【基础练习】【区间DP】codevs1090 加分二叉树题解

    2003 NOIP TG 题目描写叙述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),当中数字1,2,3,-,n为节点编号.每一个节点都有一个分数(均为正整 ...

  5. 洛谷P1040 加分二叉树(区间dp)

    P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di, ...

  6. cogs 106. [NOIP2003] 加分二叉树(区间DP)

    106. [NOIP2003] 加分二叉树 ★☆   输入文件:jfecs.in   输出文件:jfecs.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 设 一个 n ...

  7. 加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

    描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一 ...

  8. NOIP2003加分二叉树[树 区间DP]

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  9. 【Luogu】P1040加分二叉树(区间DP)

    题目链接 区间DP,因为中序遍历的性质:区间[l,r]的任何一个数都可以是该区间的根节点. 更新权值的时候记录区间的根节点,最后DFS输出. 见代码. #include<cstdio> # ...

随机推荐

  1. java 版本兼容

    Unsupported major.minor version 52.0 这个错误网上一百度一大堆,我就简单的记一下. 直译过来意思是:不支持version52.0,其中version 52.0是魔码 ...

  2. logstash解析tomcat的catalina.out日志字段

    filter { mutate { remove_field => ["@version","prospector","input", ...

  3. Oracle 12c数据库的安装

    Oracle一路走来,不知不觉中已经到了12c,最近要用这个新版本了,从oracle的官网上注册了个用户,下载了win版本64位的先试一下. (1)下载安装包 a. 到官网进行下载需要先注册一个Ora ...

  4. Android Studio 打包生成apk

    打开AndroidStudio,并且打开想要生成apk文件的项目  点击工具栏上面的“Builder”  点击“Builder”之后在下拉菜单里面可以看到“Genarate Singed APK”,点 ...

  5. ORACLE ASMLIB

    ORACLE ASMLIB   This blog post is more of a note for myself on configuring ASMLib. ASMLib is an opti ...

  6. suoermap的object.net循环遍历属性表,从数据库取数据进行更新属性字段值

    /// </summary> /// <param name="sName">图层名</param> /// <param name=&q ...

  7. C#中多集合组合实现

    C#中多集合组合使用方法,主要用到 Enumerable.Join方法 var skuInfoList = new Dictionary<int, List<long>>(); ...

  8. Java开发环境之ActiveMQ

    查看更多Java开发环境配置,请点击<Java开发环境配置大全> 柒章:ActiveMQ安装教程 1)去官网下载ActiveMQ安装包 http://activemq.apache.org ...

  9. emqx配置ssl

    1.生产自签证书 mkdir /etc/emqttd/certs/ && cd /etc/emqttd/certs/ openssl genrsa -out ca-key.pem 20 ...

  10. 【笔记】MAML-模型无关元学习算法

    目录 论文信息: Finn C, Abbeel P, Levine S. Model-agnostic meta-learning for fast adaptation of deep networ ...