code vs 1090 加分二叉树 (树形DP)
2016-04-27 19:05
756 查看
1090 加分二叉树
2003年NOIP全国联赛提高组时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题解
查看运行结果
题目描述 Description
设一个n个节点的二叉树tree的中序遍历为(l,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的前序遍历
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。
输入描述 Input Description
第1行:一个整数n(n<=30),为节点个数。
第2行:n个用空格隔开的整数,为每个节点的分数(分数<=100)
输出描述 Output Description
第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。
第2行:n个用空格隔开的整数,为该树的前序遍历。
样例输入 Sample Input
5
5 7 1 2 10
样例输出 Sample Output
145
3 1 2 4 5
数据范围及提示 Data Size & Hint
n(n<=30)
分数<=100
分类标签 Tags 点此展开
题解:f[root][l][r]表示区间l到r,以root为子树的根的最大值。每种情况只计算一次。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int n,m; long long c[100],f[100][100][100]; int rt[100][100],a[100][100],root[100][100]; long long dfs(int root,int l,int r) { if (f[root][l][r]!=-1) return f[root][l][r]; if (l==r) { rt[l][r]=l; f[l][l][r]=c[l]; return f[l][l][r]; } long left=0; long long right=0; for (int i=l;i<root;i++) { long long t=dfs(i,l,root-1); if (left<t) left=t,rt[l][root-1]=i; } for (int i=root+1;i<=r;i++) { long long t=dfs(i,root+1,r); if (right<t) right=t,rt[root+1][r]=i; } if (!left) left=1; if (!right) right=1; f[root][l][r]=left*right+c[root]; return f[root][l][r]; } void outp(int l,int r) { if (r<l) return ; printf("%d ",a[l][r]); int t=a[l][r]; outp(l,a[l][r]-1); outp(a[l][r]+1,r); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lld",&c[i]); memset(f,-1,sizeof(f)); long long ans=0; for (int i=1;i<=n;i++) { long long t=dfs(i,1,n); //cout<<t<<endl; if (ans<t) { ans=t; rt[1] =i; for (int j=1;j<=n;j++) for (int k=j;k<=n;k++) a[j][k]=rt[j][k]; } } printf("%lld\n",ans); outp(1,n); }
相关文章推荐
- LeetCode *** 344. Reverse String
- JVM - 堆外内存
- Android集成Fresco框架导致在64位机器上(三星S6,华为P8等)找不到其他so库
- 改变UITableViewCell删除状态时,改变按钮的背景颜色。
- 写连接代码时需要注意2000和2005的不同:
- 人工智能大拿解答机器学习30个问答
- PHP 使用json_encode 解析数据库查询结果, 得到 json 最外层有中括号 [ ]
- mac 端口被占用及kill端口
- 编写高质量iOS代码与OS X代码的effective 方法小结
- View的工作原理
- ios开发之从输入流里读入数据
- 【Realflow】Emitter - Emitter 节点翻译
- bnu 51644 Whalyzh's Problem(网络流,最大密度图) (北师16校赛)
- solr入门之solr安全控制的研究和实践(三) zookeeper访问控制
- 用回溯法解决0-1背包问题
- poj 1066 Treasure Hunt (线段交)
- 解决微信安卓SDK获取用户昵称时中文乱码的问题
- 微信订阅号
- unity5.3.3 no pc,mac&linux standalone
- 自定义Exception