zoukankan      html  css  js  c++  java
  • 洛谷1040 加分二叉树 区间dp

    传送门:https://www.luogu.org/problem/show?pid=1040

    题目描述

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

    样例君

    输入

    5

    5 7 1 2 10

    输出

    145

    3 1 2 4 5

    蒟蒻吐槽

      被机房dalao带着刷dp题,虽然蒟蒻更想悄咪咪地码一码线段树。

      言归正传,蒟蒻乍一看还以为是树形dp,结果是一道区间dp,和其他dp不太一样的地方,这里要在k循环时特判一下以k为根的子树没有左右儿子的情况。其他的,就和普通区间dp没什么区别了。特别的,也就是转移上一层状态时中间要把决策点k的空间留出来方便加上根的贡献。上代码了,对于区间dp还没有什么了解的战友,蒟蒻建议看一下这个博客,快照传送门普通传送门,因为蒟蒻在新疆,有的网站上不去,只有快照了,其他地方的战友应该可以上,所以有两个传送门。

      那个tr[i][j]的二维数组,记录的是区间l到r的根。代码有点丑。

      另,因为蒟蒻实在上不了csdn,如果侵权,希望原作者可以留言给我,谢谢。

    代码

    #include<cstdio>
    
    const int N=50;
    
    int n,tr[N][N];
    long long dp[N][N];
    
    void dfs(int l,int r)
    {
        if(l>r)return;
        printf("%d ",tr[l][r]);
        dfs(l,tr[l][r]-1);
        dfs(tr[l][r]+1,r);
        return;
    
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        scanf("%lld",&dp[i][i]),tr[i][i]=i;
        for(int l=2;l<=n;++l)
        {
            for(int i=1;i<=n-l+1;++i)
            {
                int j=i+l-1;
                if(j>n)break;
                for(int k=i;k<=j;++k)
                {
                    if(k==i&&dp[i][j]<dp[k+1][j]+dp[k][k])dp[i][j]=dp[k+1][j]+dp[k][k],tr[i][j]=k;
                    else if(k==j&&dp[i][j]<dp[i][k-1]+dp[k][k])dp[i][j]=dp[i][k-1]+dp[k][k],tr[i][j]=k;
                    else if(k!=i&&k!=j&&dp[i][j]<dp[i][k-1]*dp[k+1][j]+dp[k][k])
                    {
                        dp[i][j]=dp[i][k-1]*dp[k+1][j]+dp[k][k];
                        tr[i][j]=k;
                    }
                }
            }
        }
        printf("%lld
    ",dp[1][n]);
        dfs(1,n);
        return 0;
    }
  • 相关阅读:
    minGw编译器记录
    也来小谈jsonP
    [struts2]2.3.14 jsonplugin 存在bug<java.lang.NoSuchFieldException: DEFAULT_PARAM>
    年学习进度简记【2012】
    征服ExtJs那棵树(ExtJs官方开发手册汉语详解TreePanel)
    html 和ExtJs 搭建背景音乐 开发
    复习整理2
    MSChartHelpe
    DataToExcel
    如何将一个类型在FOREACH中使用
  • 原文地址:https://www.cnblogs.com/mofangk/p/7745114.html
Copyright © 2011-2022 走看看