题目描述

设一个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 加分二叉树的更多相关文章

  1. CODEVS1090 加分二叉树

    codevs1090 加分二叉树 2003年NOIP全国联赛提高组 题目描述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点 ...

  2. Vijos 1100 加分二叉树

    题目 1100 加分二叉树 2003年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB   题目描述 Description 设一个n个节点的二叉树tree的中序遍历为( ...

  3. 洛谷P1040 加分二叉树(树形dp)

    加分二叉树 时间限制: 1 Sec  内存限制: 125 MB提交: 11  解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...

  4. 【算法•日更•第十期】树型动态规划&区间动态规划:加分二叉树题解

    废话不多说,直接上题: 1580:加分二叉树 时间限制: 1000 ms         内存限制: 524288 KB提交数: 121     通过数: 91 [题目描述] 原题来自:NOIP 20 ...

  5. NOIP2003加分二叉树[树 区间DP]

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

  6. NOIP 2003解题报告

    第一题(神经网络): 题目大意,给出一些点,每个点都有2个值,c和u,给出一些有向边,权值为w.入度为0的点的c已知,其它点的c未知,每个入度不为0的点node的c等于sum(c[k]*w[k][no ...

  7. CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)

    CJOJ 1010[NOIP2003]加分二叉树 / Luogu 1040 加分二叉树(树型动态规划) Description 设 一个 n 个节点的二叉树 tree 的中序遍历为( 1,2,3,-, ...

  8. P1040 加分二叉树

    转自:(http://www.cnblogs.com/geek-007/p/7197439.html) 经典例题:加分二叉树(Luogu 1040) 设一个 n 个节点的二叉树 tree 的中序遍历为 ...

  9. 【洛谷】P1040 加分二叉树

    [洛谷]P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数 ...

  10. 【题解】NOI2009二叉查找树 + NOIP2003加分二叉树

    自己的思维能力果然还是太不够……想到了这棵树所有的性质即中序遍历不变,却并没有想到怎样利用这一点.在想这道题的过程中走入了诸多的误区,在这里想记录一下 & 从中吸取到的教训(原该可以避免的吧) ...

随机推荐

  1. PHP程序缓存之文件缓存处理方式

    PHP程序缓存之文件缓存处理方式在开发程序过程中,缓存的设置大大提升程序效率,减小数据库负载.基本配置缓存和常规配置缓存 基本配置缓存在项目开发中类似这样子的格式: 文件:config.php $CF ...

  2. C语言程序设计做题笔记之C语言基础知识(上)

    C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...

  3. 图表插件——Highcharts插件的使用(一柱状图)

    1.下载Highcharts插件 官方下载网址:http://www.highcharts.com/download 2.引入需要的js文件 <script src="~/Script ...

  4. python下redis的基本操作:

    1. 基本操作: >>> import redis >>> print redis.__file__ /usr/local/lib/python2.7/dist-p ...

  5. Android 网络请求详解

    我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的.如果使用 HTTP 协议来发送和接收网络数据,就免不了使用 HttpURLConnection 和 HttpClient ...

  6. [wikioi]四色问题

    http://wikioi.com/problem/1116/ 典型的DFS. #include <iostream> #include <memory.h> #define ...

  7. ANDROID_MARS学习笔记_S05_006_距离传感器

    import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import ...

  8. 【原创】如何构建MIPS交叉编译工具链

    运行环境:Ubuntu12.04PC提前安装库:flex,bison,libncureses5-dev,texinfo,这些库提前apt-get install.需要重新安装:gawk(先apt-ge ...

  9. 【HDOJ】3560 Graph’s Cycle Component

    并查集的路径压缩. #include <stdio.h> #include <string.h> #define MAXNUM 100005 int deg[MAXNUM], ...

  10. Javascript水平提升

    1,学习js分几个阶段,没入门,入门初学者,中级水平,高级水平,ppt水平. 2,没入门的如何学习? 我当初是先学jquery,有css和html基础,有css基础看jq的语法很简单,就是选择符,jq ...