zoukankan      html  css  js  c++  java
  • P1040 加分二叉树

    题目描述

    设一个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
    

    区间DP.
    递推不会写,以后就写记忆会搜索了。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 const int MAXN=51;
     7 int n,zx[MAXN];
     8 int dp[MAXN][MAXN];
     9 int root[MAXN][MAXN];
    10 void read(int & n)
    11 {
    12     char c='+';int x=0;bool flag=0;
    13     while(c<'0'||c>'9')
    14     {c=getchar();if(c=='-')flag=1;}
    15     while(c>='0'&&c<='9')
    16     {x=x*10+(c-48);c=getchar();}
    17     flag==1?n=-x:n=x;
    18 }
    19 int M_s(int l,int r)
    20 {
    21     dp[l][r]=1;
    22     if(l==r)
    23     {
    24         dp[l][r]=zx[l];
    25         root[l][r]=l;
    26         return zx[l];
    27     }
    28     else for(int k=l;k<=r;k++)
    29     {
    30         int lson=1,rson=1;
    31         if(dp[l][k-1])
    32             lson=dp[l][k-1];
    33         else if(l<=k-1)
    34             lson=M_s(l,k-1);
    35         if(dp[k+1][r])
    36             rson=dp[k+1][r];
    37         else if(r>k)
    38             rson=M_s(k+1,r);
    39         if(lson*rson+zx[k]>dp[l][r])
    40         {
    41             dp[l][r]=lson*rson+zx[k];
    42             root[l][r]=k;
    43         }
    44     }
    45     return dp[l][r];
    46 }
    47 void xianxu(int l,int r)
    48 {
    49     if(root[l][r])
    50     {
    51         printf("%d ",root[l][r]);
    52         xianxu(l,root[l][r]-1);
    53         xianxu(root[l][r]+1,r);
    54     }
    55 }
    56 int main()
    57 {
    58     read(n);
    59     for(int i=1;i<=n;i++)
    60         read(zx[i]);
    61     int out=M_s(1,n);
    62     printf("%d
    ",out);
    63     xianxu(1,n);
    64     return 0;
    65 }


  • 相关阅读:
    删除重复记录
    SQL Server调试存储过程
    SQL日期格式化应用大全
    阻塞分析
    Ajax原理详细说明
    varchar和nvarchar的区别
    临时表vs.表变量以及它们对SQLServer性能的影响
    Enterprise Library系列文章回顾与总结
    关于分页控件的文章
    SQL操作全集
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/7085879.html
Copyright © 2011-2022 走看看