NOIP-2003 加分二叉树
题目描述
设一个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的前序遍历
————————by洛谷oj
http://www.luogu.org/problem/show?pid=1040
显然一道树形DP 但与主流树形DP不同的是,本题的具体的树不是条件,而是所求。但好在题中还是给了树的中序遍历的(不然怎么做),于是想到中序遍历的性质,点A的左子树在A左,右子树在A右,再分析题意,显然对于每一个根节点A,她的树的加分在确定了左右儿子和儿子子树的最优加分后即可确定,后者由DP实现,前者则需要分别在两个备选点区间中枚举于是得出状态转移方程
f[fa][l][r]=a[fa]+max(f[i][l][fa-1]*f[j][fa+1][r])(i,j)∈{(a,b)|a∈[l,fa-1],b∈[fa+1,r]}
剩下的就是一些个别的处理了,如当fa-1=l或fa+1=r时特别处理下,之类的。
于是本题的第一个任务完成了,剩下建棵树。这也很简单——对于ls[fa][l][r]和rs[fa][l][r],f[fa][l][r]转移自i,j,故ls[fa][l][r]=i,rs[fa][l][r]=j;在DP的同时进行。
代码如下:
#include<cstdio>
using namespace std;
int n;
int a[];
long long f[][][];
int ls[][][],rs[][][]; long long dp(int,int,int);
void dlr(int,int,int);
int main()
{
int i,fa;
long long num=,ans=;
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<=n;i++)
{
num=dp(,n,i);
if(ans<num)
{
ans=num;
fa=i;
}
}
printf("%lld\n",ans);
dlr(,n,fa);
}
long long dp(int l,int r,int fa)
{
int i,j;
long long ans;
if(f[fa][l][r]!=)
return f[fa][l][r];
f[fa][l][r]=a[fa];
for(i=l;i<fa;i++)
{
for(j=fa+;j<=r;j++)
{
ans=a[fa]+dp(l,fa-,i)*dp(fa+,r,j);
if(f[fa][l][r]<ans)
{
f[fa][l][r]=ans;
ls[fa][l][r]=i;
rs[fa][l][r]=j;
}
}
}
if(l==fa)
{
for(j=fa+;j<=r;j++)
{
ans=a[fa]+dp(fa+,r,j);
if(f[fa][l][r]<ans)
{
f[fa][l][r]=ans;
rs[fa][l][r]=j;
}
}
}
if(r==fa)
{
for(i=l;i<fa;i++)
{
ans=a[fa]+dp(l,fa-,i);
if(f[fa][l][r]<ans)
{
f[fa][l][r]=ans;
ls[fa][l][r]=i;
}
}
}
return f[fa][l][r];
}
void dlr(int l,int r,int fa)
{
printf("%d ",fa);
if(ls[fa][l][r])
dlr(l,fa-,ls[fa][l][r]);
if(rs[fa][l][r])
dlr(fa+,r,rs[fa][l][r]);
}
当然,本题也可写成区间DP;
最后:
祝AC哟;
NOIP-2003 加分二叉树的更多相关文章
- CODEVS1090 加分二叉树
codevs1090 加分二叉树 2003年NOIP全国联赛提高组 题目描述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点 ...
- Vijos 1100 加分二叉树
题目 1100 加分二叉树 2003年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 设一个n个节点的二叉树tree的中序遍历为( ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- 【算法•日更•第十期】树型动态规划&区间动态规划:加分二叉树题解
废话不多说,直接上题: 1580:加分二叉树 时间限制: 1000 ms 内存限制: 524288 KB提交数: 121 通过数: 91 [题目描述] 原题来自:NOIP 20 ...
- NOIP2003加分二叉树[树 区间DP]
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- NOIP 2003解题报告
第一题(神经网络): 题目大意,给出一些点,每个点都有2个值,c和u,给出一些有向边,权值为w.入度为0的点的c已知,其它点的c未知,每个入度不为0的点node的c等于sum(c[k]*w[k][no ...
- CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)
CJOJ 1010[NOIP2003]加分二叉树 / Luogu 1040 加分二叉树(树型动态规划) Description 设 一个 n 个节点的二叉树 tree 的中序遍历为( 1,2,3,-, ...
- P1040 加分二叉树
转自:(http://www.cnblogs.com/geek-007/p/7197439.html) 经典例题:加分二叉树(Luogu 1040) 设一个 n 个节点的二叉树 tree 的中序遍历为 ...
- 【洛谷】P1040 加分二叉树
[洛谷]P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数 ...
- 【题解】NOI2009二叉查找树 + NOIP2003加分二叉树
自己的思维能力果然还是太不够……想到了这棵树所有的性质即中序遍历不变,却并没有想到怎样利用这一点.在想这道题的过程中走入了诸多的误区,在这里想记录一下 & 从中吸取到的教训(原该可以避免的吧) ...
随机推荐
- php中浮点数计算问题
如果用php的+-*/计算浮点数的时候,可能会遇到一些计算结果错误的问题,比如echo intval( 0.58*100 );会打印57,而不是58,这个其实是计算机底层二进制无法精确表示浮点数的一个 ...
- OC修饰词 - 内存管理
<招聘一个靠谱的 iOS>—参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外,其他54道均 ...
- Uva 10294 Arif in Dhaka (First Love Part 2)
Description 现有一颗含\(N\)个珠子的项链,每个珠子有\(t\)种不同的染色.现求在旋转置换下有多少种本质不同的项链,在旋转和翻转置换下有多少种本质不同的项链.\(N < 51,t ...
- 解决java.lang.NoClassDefFoundError: org.jdom.Content
报错:java.lang.NoClassDefFoundError: org.jdom.Content 解决办法: 更新lib目录下的jdom.jar 至最新版本.
- SDUT 2352 Run Length Encoding
点我看题目 题意 :将给定的字符串编码,编码的规则根据两条,1.如果字符串里有连续相等的字符,就变为两个字符,一个是这些连续相同的字符的个数,另一个是这个字符,但是如果数量超过了9个,那就输出9再输出 ...
- CAS单点登录配置[2]:证书生成
上一篇介绍了准备工作,本片将介绍如何生成证书. 服务器端证书 1 我们在F盘下建立一个cas文件夹,在此文件夹中生成证书文件,打开命令窗口,进入此目录下,如图: 2 生成服务器端证书, 此命令用于在当 ...
- 《ruby编程语言》笔记 1
赋值: ruby支持并行赋值,即允许在赋值表达式中出现多余一个值和多于一个的变量: x,y=1,2a,b=b,ax,y,z=[1,2,3] (python同样可以正常上面的语句). Methods i ...
- 透过表象看本质!?之二——除了最小p乘,还有PCA
如图1所示,最小p乘法求得是,而真实值到拟合曲线的距离为.那么,对应的是什么样的数据分析呢? 图1 最小p乘法的使用的误差是.真实值到拟合曲线的距离为 假如存在拟合曲线,设直线方程为.真实值到该曲线的 ...
- 17.1.4 Replication and Binary Logging Options and Variables 复制和Binary logging 选项和变量
17.1.4 Replication and Binary Logging Options and Variables 复制和Binary logging 选项和变量 下面的章节包含信息关于mysql ...
- JavaScript 判断对象是否为空
/** **判断是否null *@param data */ function isNull(data) { return (data == "" || data == u ...