博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
caioj 1106 树形动态规划(TreeDP)1:加分二叉树
阅读量:6891 次
发布时间:2019-06-27

本文共 990 字,大约阅读时间需要 3 分钟。

解这道题的前提是非常熟悉中序遍历的方式

我就是因为不熟悉而没有做出来
中序遍历是5 7 1 2 10的话,如果1是根节点
那么5 7 1就是1的左子树,2, 10就是右子树
这就有点中链式dp的味道了,实际解法也是中链式dp的解法
设f[i][j]为中序遍历从i到j的最大价值
f[l][r] = f[l][mid-1] * f[mid+1][r] + d[mid]
从小规模推到大规模
dp过程中记录根节点以求前序遍历。

#include
#define REP(i, a, b) for(int i = (a); i < (b); i++)using namespace std;const int MAXN = 30;int d[MAXN], f[MAXN][MAXN], root[MAXN][MAXN], n;void print(int l, int r){ if(l <= r) { printf("%d ", root[l][r]); print(l, root[l][r] - 1); print(root[l][r] + 1, r); }}int main(){ scanf("%d", &n); REP(i, 0, n + 1) REP(j, 0, n + 1) f[i][j] = 1; REP(i, 1, n + 1) { scanf("%d", &d[i]); f[i][i] = d[i]; root[i][i] = i; } REP(k, 2, n + 1) for(int l = 1; l + k - 1 <= n; l++) { int r = l + k - 1; REP(mid, l, r + 1) if(f[l][r] < f[l][mid-1] * f[mid+1][r] + d[mid]) { f[l][r] = f[l][mid-1] * f[mid+1][r] + d[mid]; root[l][r] = mid; } } printf("%d\n", f[1][n]); print(1, n); return 0;}

 

转载于:https://www.cnblogs.com/sugewud/p/9819399.html

你可能感兴趣的文章
解决Received unexpected end-of-file from SFTP server --ftp文件传输
查看>>
【转】Mybatis框架结构与基本原理
查看>>
kotlin lateinit
查看>>
寻找连续且重复次数最多的 string 和其次数
查看>>
空着怪冷清的!贴贴代码吧~
查看>>
oracle 的分析函数
查看>>
Dubbo的Api+Provider+Customer示例(IDEA+Maven+Springboot+dubbo)
查看>>
如何实现文件的上传
查看>>
WiFi的一些事儿
查看>>
使用open-falcon监控Nginx
查看>>
风的季节
查看>>
系统架构-设计模式(适配器、观察者、代理、抽象工厂等)及架构模式(C/S、B/S、分布式、SOA、SaaS)(干货)...
查看>>
0516Python基础-迭代器-生成器
查看>>
使用exec命令删除前几天产生的日志
查看>>
原生JS实现省市区(县)三级联动选择
查看>>
angular.extend用法实例
查看>>
CSS (看得懂就好)
查看>>
Postgresql中时间戳与日期的相互转换(同样适用于GreenPlum)
查看>>
50个必备的jquery代码段
查看>>
哥伦布计划
查看>>