zoukankan      html  css  js  c++  java
  • Luogu 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


    参考博客https://www.cnblogs.com/L-Memory/p/7353689.html

     1 //2018年4月5日11:17:08
     2 #include <iostream>
     3 #include <cstdio> 
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 const int N = 31; 
     8 int n;
     9 ll f[N][N];
    10 int num[N][N];
    11 int w[N];
    12 
    13 void find(int x, int y){
    14     if(x <= y){
    15         printf("%d ", num[x][y]);
    16         find(x, num[x][y]-1);
    17         find(num[x][y]+1, y);
    18     }
    19 }
    20 
    21 int main(){
    22     scanf("%d", &n);
    23     for(int i=0; i<=n; i++)
    24         for(int j=0; j<=n; j++){
    25             f[i][j] = 1; num[i][i] = i;
    26         }
    27     for(int i=1; i<=n; i++){
    28         scanf("%d", &f[i][i]);
    29     }
    30     for(int i=n; i>=1; i--) //***** 
    31         for(int j=i+1; j<=n; j++)
    32             for(int k=i; k<=j; k++){
    33                 if(f[i][j] < f[i][k-1]*f[k+1][j] + f[k][k])
    34                     f[i][j] = f[i][k-1]*f[k+1][j] + f[k][k], num[i][j] = k;
    35             }
    36     printf("%lld
    ", f[1][n]);
    37     find(1, n);
    38     
    39     return 0;
    40 }

     

    还有记忆化搜索的写法,可以参考https://www.cnblogs.com/oscar-cnblogs/p/8670212.html

     1 //2018年4月5日11:57:39
     2 #include <iostream>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 
     8 const int N = 31;
     9 int a[N];
    10 int f[N][N];
    11 int root[N][N];
    12 int n;
    13 
    14 int dfs(int l, int r){
    15     if(l > r) return 1;
    16     if(f[l][r] > 0) return f[l][r];
    17     if(l == r){
    18         root[l][r] = l;
    19         f[l][r] = a[l];
    20         return f[l][r];
    21     }
    22     for(int i=l; i<=r; i++){
    23         int res = dfs(l, i-1)*dfs(i+1, r) + a[i];
    24         if(res > f[l][r]){
    25             f[l][r] = res;
    26             root[l][r] = i;
    27         }
    28     }
    29     return f[l][r];
    30     
    31 }
    32 
    33 void print(int l, int r){
    34     if(l > r) return;
    35     if(l == r){
    36         printf("%d ", root[l][r]);
    37         return;
    38     }
    39     printf("%d ", root[l][r]);
    40     print(l, root[l][r]-1);
    41     print(root[l][r]+1, r);
    42 }
    43  
    44 
    45 int main(){
    46     scanf("%d", &n);
    47     for(int i=1; i<=n; i++) scanf("%d", &a[i]);
    48     printf("%d
    ", dfs(1, n));
    49     print(1, n);
    50 
    51     return 0;
    52 }
  • 相关阅读:
    在Ubuntu-20.04上安装Emacs-27.1
    VSCode 配置 C++ 与 python 编译环境
    cf 1557(div2)
    2021牛客暑期多校训练营8
    2021牛客暑期多校训练营7
    2021暑期cf加训3
    2021牛客暑期多校训练营6
    2021牛客暑期多校训练营5
    3ds Max基本操作
    renren-generator快速生成你搬砖需要的CRUD代码的框架
  • 原文地址:https://www.cnblogs.com/sineagle/p/8721741.html
Copyright © 2011-2022 走看看