http://www.luogu.org/problem/show?pid=1040

题目描述

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

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

输出格式:

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

第2行:n个用空格隔开的整数,为该树的前序遍历。

一开始写的是在算可以取得的最大值的时候计算每个节点的左右儿子,然而这个思路并不对...因为数据规模较小,DP求完最大值后可以再记忆化搜索一次来打印先序遍历,因为第一次已经求出了所有情况的值,所以第二次DP很快

 #include<iostream>
 #include<cstdio>
 #include<cstring>
 using namespace std;
 struct Node{
     int root;
     long long val;
 };
 ;
 long long mem[maxn][maxn];
 int v[maxn][maxn],lson[maxn],rson[maxn],num[maxn],fa[maxn][maxn],n;
 int init(){
     memset(v,,sizeof(v));
     memset(lson,,sizeof(lson));
     memset(rson,,sizeof(rson));
     memset(fa,,sizeof(fa));
 }
 Node dp(int l,int r){
     if(v[l][r]) return (Node){fa[l][r],mem[l][r]};
     v[l][r]=;
     ,tfa=-;
     if(l==r){
         mem[l][r]=num[l];
         fa[l][r]=l;
         return (Node){l,num[l]};
     }
     tfa=l;ans=dp(l+,r).val+num[l];
     ).val+num[r];
     if(x>ans) ans=x,tfa=r;
     ;i<r;i++){
         x=dp(l,i-).val*dp(i+,r).val+num[i];
         if(x>ans) ans=x,tfa=i;
     }
     ,r).root;
     ).root;
     else{
         lson[tfa]=dp(l,tfa-).root;
         rson[tfa]=dp(tfa+,r).root;
     }
     mem[l][r]=ans,fa[l][r]=tfa;
     return (Node){tfa,ans};
 }
 void print(int l,int r){
     if(l==r){
         printf("%d ",l);
         return;
     }
     ,r).val+num[l];int f=l;
     ).val+num[r];
     if(x>ans) ans=x,f=r;
     ;i<r;i++){
         x=dp(l,i-).val*dp(i+,r).val+num[i];
         if(x>ans) ans=x,f=i;
     }
     printf("%d ",f);
     if(f==l){
         print(l+,r);
     }else if(f==r){
         print(l,r-);
     }else{
         print(l,f-);
         print(f+,r);
     }
 }
 void dfs(int u){
     printf("%d ",u);
     if(lson[u]) dfs(lson[u]);
     if(rson[u]) dfs(rson[u]);
 }
 int main()
 {
     scanf("%d",&n);
     init();
     ;i<=n;i++) scanf("%d",&num[i]);
     printf(,n).val);
     //dfs(dp(1,n).root);
     print(,n);
     ;
 }

NOIP2003 加分二叉树的更多相关文章

  1. cogs 106. [NOIP2003] 加分二叉树(区间DP)

    106. [NOIP2003] 加分二叉树 ★☆   输入文件:jfecs.in   输出文件:jfecs.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 设 一个 n ...

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

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

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

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

  4. NOIP-2003 加分二叉树

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

  5. NOIP2003加分二叉树

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

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

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

  7. 加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

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

  8. CODEVS1090 加分二叉树

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

  9. Vijos 1100 加分二叉树

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

随机推荐

  1. JavaScript的jsonp

    目录索引: 一.AJAX的概念二.POST && GET三.原生实现AJAX简单示例 3.1 实现代码 3.2 重点说明四.框架隐藏域 4.1 基本概念 4.2 后台写入脚本 4.3 ...

  2. MVC项目发布错误

    下面各个方法尝试采用: 重装Framework 32位的Windows: --------------------------------------------------------------- ...

  3. Weblogic重启(转载)

    1.用户名密码登录. 2.切换到weblogic的bin目录下: cd /user/local/weblogic/user_projects/domains/base_domain/bin/ 3.先停 ...

  4. Getting started with SciPy for .NET

    Getting started with SciPy for .NET 1.) IronPython Download and install IronPython 2.7, this will re ...

  5. jdk之jhat命令

    jhat命令 -- JavaHeap Analyse Tool 用途:是用来分析Java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言第一步:导出堆  ...

  6. Replace JSON.NET with ServiceStack.Text in ASP.NET Web API

    Because ServiceStack.Text performs much better I recently stumbled across a comparison of JSON seria ...

  7. play framework (一)

    Playframework--像玩一样编程, 传说中有了它,放个猴子在电脑前都会编程了! http://developer.51cto.com/art/201202/320053.htm http:/ ...

  8. [Java] 内部类的用法

    package test.file; import java.io.File; import java.io.FilenameFilter; /** * 内部类的使用 * @author Frost. ...

  9. [ActionScript 3.0] AS3 绘制立方体

    package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Vector3D; import ...

  10. (easy)LeetCode 204.Count Primes

    Description: Count the number of prime numbers less than a non-negative number, n. Credits:Special t ...