加分二叉树

题目传送门

题目描述

设一个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,为节点个数。

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

输出格式

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

第2行:n个用空格隔开的整数,为该树的前序遍历。如果存在多种方案,则输出字典序最小的方案。

数据范围

n<30

输入样例:

5
5 7 1 2 10

输出样例:

145
3 1 2 4 5

题解:

区间DP同样适用于二叉树:

枚举二叉树的节点个数 len, 枚举二叉树的组成区间(l, r), 枚举根节点 k, 从而得到状态转移方程式:

f[ l ] [ r ] = max(f[ l ] [ r ], f[ l ] [ k - 1] + f[ l ] [k + 1], + w[k])

更新最大值的同时, 记录每一个树的根节点

//DP[i][j] 表示区间[i ~ j] 表示为一个二叉树时的分数的最大值
#include<iostream>
using namespace std;
const int N = 35;
int n;
int w[N];
int f[N][N], g[N][N]; // g数组用来存储每一个区间的根节点
void dfs(int l, int r, int k)
{if(l > r)return ;cout << k << ' ';dfs(l, k - 1, g[l][k - 1]);dfs(k + 1, r, g[k + 1][r]);
}
int main()
{cin >> n;for(int i = 1; i <= n; i++)cin >> w[i];for(int len = 1; len <= n; len++){   //枚举区间长度for(int l = 1; l + len - 1 <= n; l++){ //枚举起点int r = l + len - 1;  //得到右端点if(len == 1){  //如果是根节点f[l][r] = w[l]; g[l][r] = l;}else{for(int k = l; k <= r; k++){  //枚举根节点//判断左子树是否为空int left = k == l ? 1 : f[l][k - 1];  //得到左子树和右子树的分数int right = k == r ? 1 : f[k + 1][r];if(left * right + w[k] > f[l][r]){   //更新最大值f[l][r] = left * right + w[k];g[l][r] = k;  //跟新根节点}}}}}cout << f[1][n] << endl;dfs(1, n, g[1][n]);return 0;
}

AcWing479.加分二叉树(区间DP)题解相关推荐

  1. AcWing1069.凸多边形的划分(区间DP)题解

    凸多边形的划分 题目传送门 题目描述 给定一个具有 N 个顶点的凸多边形,将顶点从 1 至 N 标号,每个顶点的权值都是一个正整数. 将这个凸多边形划分成 N−2 个互不相交的三角形,对于每个三角形, ...

  2. AcWing.282石子合并(区间DP)题解

    石子合并 题目描述 设有N堆石子排成一排,其编号为1,2,3,-,N. 每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆. 每次只能合并相邻的两堆,合并的代价为这两堆石子的质 ...

  3. P1040 加分二叉树【dp+深搜】

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

  4. AcWing321.棋盘分割(区间DP)题解

    棋盘分割 题目传送门 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘 ...

  5. 区间dp入门——总结+习题+解析

    前天学长拉了个区间dp的专题,花了两个做,今天就来做个总结吧!!! 区间dp其实就是一种建立在线性结构上的对区间的动态规划,dp本来就是很奇妙的东西,也没有什么套路,就是一种思考的数学思维方式,只有做 ...

  6. 【树形区间DP】加分二叉树(ssl 1033/luogu 1040)

    加分二叉树 ssl 1033 luogu 1040 题目大意: 有一棵中序遍历为1,2,3-n的二叉树(当然二叉树的样子没有固定),现在给出每个节点的分数,一个节点的加数=两个子节点的加数相乘+当前节 ...

  7. DP专练1( [NOIP 2003]加分二叉树 + 太空梯 )

    我们先慢慢来 加分二叉树 题目 题解 简单讲解前序//中序//后序遍历 代码实现 太空梯 题目 题解 代码实现 加分二叉树 题目 题解 简单讲解前序//中序//后序遍历 其实说白了,这个*序就是根ro ...

  8. 【树型DP】加分二叉树

    问题 b: [树型DP]加分二叉树 时间限制: 1 Sec  内存限制: 64 MB 提交: 8  解决: 6 [提交] [状态] [讨论版] [命题人:admin] 题目描述 科技忽略了过程就是魔法 ...

  9. CSP认证201612-4 压缩编码[C++题解]:区间dp、huffman树、石子合并

    题目分析 来源:acwing 分析: 本题难在想到是区间dp.想到区间dp之后,这就是石子合并的代码直接默写. 那么是如何建模的呢?我们把huffman编码(这里要求按照字典序大小编码,和huffma ...

最新文章

  1. 麻省理工人工智能实验室发现更小更容易训练的神经网络
  2. 计算机数控装置论文,数控专业(论文)范文.doc
  3. Winform将网页生成图片
  4. java基础之访问控制符
  5. PDF数据防扩散系统方案
  6. centos 初学者_初学者:如何在Outlook 2013中创建和管理任务
  7. 一张图看懂阿里云网络产品[二] 专有网络VPC
  8. vsftpd 启动 vsftpd:500 OOPS: bad bool value in config file for: guest_enable
  9. java工具类与集合类_JAVA学习---集合和工具类
  10. oracle 除法问题,javascript中除法问题
  11. 从数组中删除最后一项
  12. 在前台或会员中心获取表单向导里提交的数据
  13. iOS xcode The certificate used to sign Administrator has either expired or has been revoked. An u
  14. 软件工程中的十三种文档
  15. 从混沌熬到风口:移动FM的五年之争
  16. Hadoop单机版安装
  17. 深入理解HTTP/HTTPS协议
  18. 百乐达斯城全新梦幻主题乐园幻乐堡在韩国开业
  19. 使用POI为Excel添加数据有效性验证
  20. PCI-Express转4串/8串/28串口CH384的硬件配置及设计

热门文章

  1. 关于C# DataGridView 全选与取消的小问题
  2. 【C#】带等待窗体的BackgroundWorker
  3. Linux 搭建SVN server
  4. hdu 2046 骨牌铺方格
  5. js学习总结----js中常用的四种输出方式
  6. Oracle ------ SQLDeveloper中SQL语句格式化快捷键
  7. java读取.properties文件乱码
  8. oracle学用命令大全 笔记
  9. Silverlight 国外技术文章
  10. 【css练习】斑马线表格,美人尖,断线下划线