• NOIP2003 加分二叉树


    题三    加分二叉树

    【问题描述】

        设一个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的前序遍历

    【输入格式】

        第1行:一个整数n(n<30),为节点个数。

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

    【输出格式】

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

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

    【输入样例】

        5

        5 7 1 2 10

    【输出样例】

        145

        3 1 2 4 5

    【思路】

      区间DP

      设d[i][j]为结点范围为ij的最优构造所得分数。

      状态转移方程:

    D[i][j]=max(d[i][j],d[i][k-1]*d[k+1][j]+A[k])

      用记忆化搜索好一些。

      至于输出前序遍历,只需要加一个p[i][j]数组,相应记录ij区间内做的选择。Print按照前序遍历输出。

    【代码】

     1 #include<iostream>
     2 #include<cstring>
     3 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     4 using namespace std;
     5 
     6 const int maxn = 30+10;
     7 int d[maxn][maxn],p[maxn][maxn];
     8 int A[maxn];
     9 int n;
    10 
    11 int dp(int s,int t) {
    12     if(d[s][t]) return d[s][t];
    13     
    14     if(t<s) return 1;
    15     if(s==t) { p[s][s]=s; return A[s]; }
    16     
    17     FOR(k,s,t) {
    18         int tmp=dp(s,k-1)*dp(k+1,t)+A[k];
    19         if(tmp>d[s][t]) {
    20             d[s][t]=tmp;
    21             p[s][t]=k;
    22         }
    23     }
    24     return d[s][t];
    25 }
    26 void print(int s,int t) {
    27     if(!p[s][t]) return ;
    28     cout<<p[s][t]<<" ";
    29     print(s,p[s][t]-1);
    30     print(p[s][t]+1,t);
    31 }
    32 int main() {
    33     ios::sync_with_stdio(false);
    34     cin>>n;
    35     FOR(i,1,n) cin>>A[i];
    36     cout<<dp(1,n)<<"
    ";
    37     print(1,n);
    38     return 0;
    39 }
  • 相关阅读:
    Pycharm快捷键
    unittest自动化测试框架
    Python简介
    Git工作流介绍
    GitFlow ⼯作流
    go 整分钟开始执行程序
    vue 保留两位小数
    vue 格式化时间戳
    Supervisor-进程守护工具
    为什么计算机语言中的变量名都不能以数字开头呢?
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4859508.html
Copyright © 2020-2023  润新知