CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)

Description

设 一个 n 个节点的二叉树 tree 的中序遍历为( 1,2,3,…,n ),其中数字 1,2,3,…,n 为节点编号。每个节点都有一个分数(均为正整数),记第 j 个节点的分数为 di , tree 及它的每个子树都有一个加分,任一棵子树 subtree (也包含 tree 本身)的加分计算方法如下: subtree 的左子树的加分 × subtree 的右子树的加分+ subtree 的根的分数;若某个子树为空,规定其加分为 1 ,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

试求一棵符合中序遍历为( 1,2,3,…,n )且加分最高的二叉树 tree 。要求输出;

( 1 ) tree 的最高加分

( 2 ) tree 的前序遍历

Input

第 1 行:一个整数 n ( n < 30 ),为节点个数。

第 2 行: n 个用空格隔开的整数,为每个节点的分数(分数< 100 )。

Output

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

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

Sample Input

5

5 7 1 2 10

Sample Output

145

3 1 2 4 5

Http

CJOJ:http://oj.changjun.com.cn/problem/detail/pid/1010

Luogu:https://www.luogu.org/problem/show?pid=1040

CodeVS:http://codevs.cn/problem/1090/

Source

树型动态规划

解决思路

因为题目给出的是中序遍历,所以有任意一棵子树的中序遍历一定是在一段里面的,我么令F[i][j]表示从i到j的最大加分,用Mayuri[i][j]表示i,j能得到最大加分的根节点。

那么我们可以枚举[i,j]之间的一个点k为根节点,得到状态转移方程F[i][j]=max(F[i][k-1]*F[k+1][j]+Value[k])同时更新Mayuri[i][j],最后的结果就是F[1][n]。

最后输出,这里我们采用递归调用的方法,在主函数里调用Outp(1,n),对于Outp(i,j)来说,我们调用Outp(i,Mayuri[i]-1) Outp(Mayuri[i]+1,j),分别按照前序遍历输出。

需要注意的是各个变量的初始值赋值,具体请看代码。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxsize=100;
const int inf=2147483647; int n;
long long Node[maxsize];//存放每个点的权值
long long F[maxsize][maxsize];//F[i][j]如题解中所示
int Mayuri[maxsize][maxsize];//Mayuri[i][j]表示i,j这棵树的根节点 void Outp(int l,int r); int main()
{
memset(F,0,sizeof(F));
cin>>n;
for (int i=1;i<=n;i++)
cin>>Node[i];
for (int i=1;i<=n;i++)
F[i][i-1]=1;//F[][]的初始化
for (int i=1;i<=n;i++)
{
F[i][i]=Node[i];//F的初始化
Mayuri[i][i]=i;//Mayuri的初始化
}
for (int i=n;i>=1;i--)
{
for (int j=i+1;j<=n;j++)
{
for (int k=i;k<=j;k++)
if (F[i][k-1]*F[k+1][j]+Node[k]>F[i][j])
{
F[i][j]=F[i][k-1]*F[k+1][j]+Node[k];
Mayuri[i][j]=k;
//cout<<"Update : "<<i<<' '<<j<<' '<<k<<' '<<F[i][j]<<endl;
}
}
}
cout<<F[1][n]<<endl;
Outp(1,n);//递归输出前序遍历
cout<<endl;
return 0;
} void Outp(int l,int r)
{
if (l>r)
return;
cout<<Mayuri[l][r]<<' ';//因为是前序遍历,所以先输出根节点
if (l==r)
return;
Outp(l,Mayuri[l][r]-1);//递归调用
Outp(Mayuri[l][r]+1,r);
return;
}

CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)的更多相关文章

  1. 【算法•日更•第十期】树型动态规划&区间动态规划:加分二叉树题解

    废话不多说,直接上题: 1580:加分二叉树 时间限制: 1000 ms         内存限制: 524288 KB提交数: 121     通过数: 91 [题目描述] 原题来自:NOIP 20 ...

  2. CJOJ 2171 火车站开饭店(树型动态规划)

    CJOJ 2171 火车站开饭店(树型动态规划) Description 政府邀请了你在火车站开饭店,但不允许同时在两个相连的火车站开.任意两个火车站有且只有一条路径,每个火车站最多有 50 个和它相 ...

  3. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  4. C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历、中序遍历、后续遍历)

    树 利用顺序存储和链式存储的特点,可以实现树的存储结构的表示,具体表示法有很多种. 1)双亲表示法:在每个结点中,附设一个指示器指示其双亲结点在数组中的位置. 2)孩子表示法:把每个结点的孩子排列起来 ...

  5. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  6. Luogu 1437 [HNOI2004]敲砖块 (动态规划)

    Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...

  7. [Luogu 4092] HEOI/TJOI2016 树

    [Luogu 4092] HEOI/TJOI2016 树 搜了树剖标签不知道怎么就跳出了个暴搜题啊! 管他既然做了就发上来吧- 有修改标签就向下搜并修改,遇到标签即停止. 这题是真的真的短. #inc ...

  8. SDUT OJ 数据结构实验之二叉树二:遍历二叉树

    数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

  9. javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

    赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...

随机推荐

  1. sChart.js:一个小型简单的图表库

    介绍 sChart.js 作为一个小型简单的图表库,没有过多的图表类型,只包含了柱状图.折线图.饼状图和环形图四种基本的图表.麻雀虽小,五脏俱全.sChart.js 基本可以满足这四种图表的需求.而它 ...

  2. (转) Java RMI 框架(远程方法调用)

    "原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://haolloyin.blog.51cto.com/1177454/33 ...

  3. Python之正则表达式(re模块)

    本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 正则表达式(Regluar Expressions)又称规则 ...

  4. JS/jQ常用宽高及应用

    关于js的宽高,随便一搜就是一大堆.这个一大堆对我来说可不是什么好事,看的头都大了.所以今天就总结了一些比较会常用的,并说明一下应用场景. 先来扯一下documentElement和body的微妙关系 ...

  5. angularjs应用prerender.io 搜索引擎优化实践

    上一篇博文(http://www.cnblogs.com/ideal-lx/p/5625428.html)介绍了单页面搜索引擎优化的原理,以及介绍了两个开源框架的优劣.prerender框架的工作原理 ...

  6. Python给小说做词云

    闲暇时间喜欢看小说,就想着给小说做词云,展示小说的主要内容.开发语言是Python,主要用到的库有wordcloud.jieba.scipy.代码很简单,首先用jieba.cut()函数做分词,生成以 ...

  7. ue4玄学画面设置实现

    pc端项目临近发布之时,免不了向玩家提供一些自订选项,以适应各自的习惯和机能,画面设置就是必要的一环. 主要的画面选项有: 1.全屏/窗口化 2.分辨率 3.视野距离 4.抗锯齿 5.后期处理 6.阴 ...

  8. [0] 服务器 TCP 提供程序无法在 [ 'any' <ipv4> *] 上侦听。TCP 端口已在使用中。

    配置工具——配置管理器——SQLEXPRESS协议下的TCP/IP协议 将其已启用改为禁用. 同时停止SQLEXPRESS服务即可

  9. Ipython 自动重载

    一. 使用示例 In [1]: %load_ext autoreload In [2]: %autoreload 2 # Reload all modules (except those exclud ...

  10. java 局部变量几点笔记

    1.局部变量的作用时间很短暂,都被存储在方法的栈内存中:2.(没使用static)非静态变量=实例变量:(使用static)静态变量=类变量3.成员变量:类体内定义的变量:4.局部变量有三种:1)形参 ...