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

    题目:

     思路:

    这题在一个细节上很奇怪,它给树是按中序遍历给的

    而且只给了中序遍历

    这意味着我们可以通过自己的方式来构造这棵树

    我们回想一下——

    在中序遍历中,一个根节点的左儿子是?

    ——这个节点的左边所有

    右儿子是?

    ——右半部分

    如果用区间表示呢?

    ——[i.k-1],[k+1,j]

    为什么没有k?

    ——根节点不在左右儿子之列

    我们一回来看这道题,发现区间DP简直是专门设计出来解决这类题的

    枚举k,利用左右区间值计算大区间值

    基本就是区间DP用惯了的套路

    至于输出遍历

    只要在DP时记下这个区间的根,然后递归即可

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    long long n;
    long long f[50][50], root[50][50];
    void print(long long l, long long r)
    {
        if (l > r)
            return;
        cout << root[l][r] << ' ';
        if (l == r)
            return;
        print(l, root[l][r] - 1);
        print(root[l][r] + 1, r);
    }
    int main()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> f[i][i];
            f[i][i - 1] = 1;
            root[i][i] = i;
        }
        for (int len = 1; len <= n; len++)
        {
            for (int i = 1; i + len <= n; i++)
            {
                int j = i + len;
                f[i][j] = f[i][i] + f[i + 1][j];
                root[i][j] = i;
                for (int k = i + 1; k < j; k++)
                {
                    if (f[i][j] < f[i][k - 1] * f[k + 1][j] + f[k][k])
                    {
                        f[i][j] = f[i][k - 1] * f[k + 1][j] + f[k][k];
                        root[i][j] = k;
                    }
                }
            }
        }
        cout << f[1][n] << endl;
        print(1, n);
        return 0;
    }
  • 相关阅读:
    python的dict和set
    python基础之dict和set
    python基础之条件判断和循环
    mongodb安装和配置,遇到问题和解决方法
    mybatis12--一级缓存
    mybatis11--多对多关联查询
    mybatis10--自连接多对一查询
    mybatis09--自连接一对多查询
    mybatis08--关联查询多对一
    mybatis07--关联查询一对多
  • 原文地址:https://www.cnblogs.com/lujin49/p/13836186.html
Copyright © 2011-2022 走看看