CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)
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 加分二叉树(树型动态规划)的更多相关文章
- 【算法•日更•第十期】树型动态规划&区间动态规划:加分二叉树题解
废话不多说,直接上题: 1580:加分二叉树 时间限制: 1000 ms 内存限制: 524288 KB提交数: 121 通过数: 91 [题目描述] 原题来自:NOIP 20 ...
- CJOJ 2171 火车站开饭店(树型动态规划)
CJOJ 2171 火车站开饭店(树型动态规划) Description 政府邀请了你在火车站开饭店,但不允许同时在两个相连的火车站开.任意两个火车站有且只有一条路径,每个火车站最多有 50 个和它相 ...
- CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)
CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...
- C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历、中序遍历、后续遍历)
树 利用顺序存储和链式存储的特点,可以实现树的存储结构的表示,具体表示法有很多种. 1)双亲表示法:在每个结点中,附设一个指示器指示其双亲结点在数组中的位置. 2)孩子表示法:把每个结点的孩子排列起来 ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- Luogu 1437 [HNOI2004]敲砖块 (动态规划)
Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...
- [Luogu 4092] HEOI/TJOI2016 树
[Luogu 4092] HEOI/TJOI2016 树 搜了树剖标签不知道怎么就跳出了个暴搜题啊! 管他既然做了就发上来吧- 有修改标签就向下搜并修改,遇到标签即停止. 这题是真的真的短. #inc ...
- SDUT OJ 数据结构实验之二叉树二:遍历二叉树
数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
随机推荐
- HttpClien Get&Post
新公司上班第二周,开始进军.Net Core,这方面的东西比较新,所以已经封装好的东西比较少,比如HttpClien之类的开源类库,找了NuGet好久,没有找到,所以先写个简陋的来用着先. 引用: u ...
- Web缓存相关知识整理
一.前言 工作上遇到一个这样的需求,一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面.用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了 ...
- Windows 修改电脑属性(一)
修改电脑属性里的注册信息 修改电脑属性的注册信息 运行注册表的方法:开始→运行→regedit→确定 1.CPU型号可以注册表编辑器中定位到下面的位置: HKEY_LOCAL_MACHINE\HARD ...
- 安装ecshop的问题处理
在安装Ecshop的时候,会遇到几个问题: 1.Strict Standards: Non-static method cls_image::gd_version() should not be ca ...
- Java使用条件语句和循环结构确定控制流
与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流.本文将简单讲解条件.循环和switch. 一.块作用域 块(block),即复合语句.是指由一对大括号括起来的若干条简单的Java语句 ...
- JavaScript函数认识,Js中的常见函数
JavaScript函数: 也称为方法,用来存储一块代码,需要的时候调用. 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 函数需要包含四要素:返回类型,函数名,参数列表,函数体 拓展: ...
- cal日历工具的用法
cal的基本语法:$ cal [month] [year] 1.显示当前月的日历 $ cal 2.显示某年的日历 $ cal 2015 3.显示某年某月日历 $ cal 12 2015 =-=-=-= ...
- jQuery未定义错误原因(jQuery is not define)
使用jQuery时,必须把它写在最前面,这样浏览器才会先加载jQuery,否则会提示缺少对象. 正确 <script type="text/javascript" src=& ...
- js动态参数作为Object的属性取值
js动态参数作为Object的属性取值var myObj = {"a":1,"b":2};var a = 'a';myObj[a] 就可以获取到 属性a的值了
- 合并静态库出现 can't move temporary file错误
静态库的制作就不说了很简单,网上也很多例子,这里主要讲下我合并通用静态库时候遇见的坑,在合并前注意.a文件一定要正确,我有一次scheme选了release但是device忘了换,结果怼着两个模拟器静 ...