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

    题目描述

    设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第ii个节点的分数为di,treedi,tree及它的每个子树都有一个加分,任一棵子树subtreesubtree(也包含treetree本身)的加分计算方法如下:

    subtreesubtree的左子树的加分× subtreesubtree的右子树的加分+subtreesubtree的根的分数。

    若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

    试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树treetree。要求输出;

    (1)treetree的最高加分

    (2)treetree的前序遍历

    输入输出格式

    输入格式:

     

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

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

     

    输出格式:

     

    1行:1个整数,为最高加分(Ans4,000,000,000)。

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

    输入输出样例

    输入样例#1: 
    5
    5 7 1 2 10
    
    输出样例#1: 
    145
    3 1 2 4 5

    解题思路:
    一道区间DP题,题目给了树的中序遍历,那么我们可以知道每个节点的左边肯定是它的左子树,右边肯定是它的右子树,那么我们就可以用一个数组f[i][x]表示i到x区间的子树最大值,设置一个断点j,枚举区间内的根节点,由此结合题意中的一个子树和=左子树和*右子树和+根节点,得出状态状态转移方程
    f[i][x] = max(f[i][x],f[i][j-1]*f[j+1][x]+f[j][j]),在状态转移时,记录根节点,以便后面输出前序遍历.

    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 long long n,f[35][35],gen[35][35];
     4 void dfs(int l,int r) {//递归求先序遍历 
     5     if(l > r) return ;
     6     if(l == r) {
     7         cout << gen[l][r] << ' ';
     8         return ;
     9     }
    10     cout << gen[l][r] << ' ';
    11     dfs(l, gen[l][r] - 1);
    12     dfs(gen[l][r] + 1, r);
    13 }
    14 int main()
    15 {
    16     cin >> n;
    17     for(int i = 1;i <= n; i++) {
    18         cin >> f[i][i];    
    19         f[i][i-1] = 1;
    20         gen[i][i] = i;//初始化每个节点的根为自己 
    21     }
    22     for(int i = n;i >= 1; i--) 
    23         for(int x = i + 1;x <= n; x++)
    24             for(int j = i;j <= x; j++)
    25                 if(f[i][j-1]*f[j+1][x]+f[j][j] > f[i][x]) {
    26                     f[i][x] = f[i][j-1]*f[j+1][x]+f[j][j];//状态转移 
    27                     gen[i][x] = j;//记录根节点 
    28                 }
    29     cout << f[1][n] <<endl;//求1到n的最大和 
    30     dfs(1,n);
    31     
    32 
    33 return 0;
    34 }
    
    

     //NOIP提高 2003 T3

     
    
    
    
    
    
    
  • 相关阅读:
    jquery的promise和es6的promise的区别
    vue源码
    Paging through lots of data efficiently (and in an Ajax way) with ASP.NET 2.0
    laydate 1.1 下拉日期挡住的bug修复
    Microsoft SQL Server 2008 R2 官方简体中文正式版下载(附激活序列号密钥)
    使用ASP.NET Treeview显示数据库里DataTable里的数据。
    [C# .NET] 数组排序 Arrays
    字符串数据按照大小排序
    Chrome浏览器中的三种刷新模式
    『TensorFlow』lookup.index_table_from_tensor查找表映射函数
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/10354206.html
Copyright © 2011-2022 走看看