zoukankan      html  css  js  c++  java
  • [NOIP2003]加分二叉树

    题目描述

      设一个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个用空格隔开的整数,为该树的前序遍历。

    输入输出样例

    输入样例#1:

    5
    5 7 1 2 10
    

    输出样例#1:

    145
    3 1 2 4 5

    思路

      f[i,j]是中序遍历为从i到j时的最大加分。

      枚举所有的可能中序遍历结果,枚举当前中序遍历中所有可能的根节点。

      转移方程:f[i,j]:=max(f[i,k-1]*f[k+1,j]+a[k])

           (i<k<j)

      初始化:f[i,j]=1;f[i,i]:=a[i];

    var a:array[1..100] of longint;  
        root,f:array[0..100,0..100] of longint;  
        n:longint;  
      
    procedure init;  
    var i:longint;  
    begin  
        readln(n);  
        for i:=1 to n do read(a[i]);  
    end;  
      
    procedure dp();  
    var i,j,p,k:longint;  
    begin  
        for i:=0 to n do  
            for j:=0 to n do  
                f[i,j]:=1;  
        for i:=1 to n do  
            begin  
                f[i,i]:=a[i];  
                root[i,i]:=i;  
            end;  
        for p:=1 to n-1 do  
            for i:=1 to n-p do  
                begin  
                    j:=i+p;  
                    f[i,j]:=0;  
                    for k:=i to j do  
                        if f[i,j]<f[i,k-1]*f[k+1,j]+a[k] then  
                            begin  
                                f[i,j]:=f[i,k-1]*f[k+1,j]+a[k];  
                                root[i,j]:=k;  
                            end;  
                end;  
    end;  
      
    procedure mid(i,j:longint);  
    begin  
        if i<=j then  
            begin  
                write(root[i,j],' ');  
                mid(i,root[i,j]-1);  
                mid(root[i,j]+1,j);  
            end;  
    end;  
      
    begin  
        init;  
        dp();  
        writeln(f[1,n]);  
        mid(1,n);  
    end.  
    View Code
  • 相关阅读:
    WindowsPhone7 经典3D游戏《刺客信条》评测
    WPF案例 — 展厅触摸屏展示系统
    Silverlight三维柱状图3D饼图的Silverlight图表组件案例
    应聘Silverlight讲师(全职或兼职均可)
    WPF案例之生产线控制器管理系统
    Silverlight 5 Beta 版发布日期确定
    《银光志Silverlight 3.0开发详解与最佳实践》发行第三版总销量过万册
    微软Silverlight5发布会提供线上注册
    Silverlight WebOS案例2.0版本(基于Silverlight4开发的Web操作系统)
    长年承接WP7游戏和WP7软件外包
  • 原文地址:https://www.cnblogs.com/yangqingli/p/4906447.html
Copyright © 2011-2022 走看看