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

    传送门

    又是熟悉的遍历题……好了又不会了。

    这是一道很神奇的题,虽然可以称为树形DP但是它不需要建树!

    首先,因为中序遍历每个连续的一段都对应一棵子树,所以我们完全可以使用区间DP的方法去把小区间合并成大区间来计算。

    使用dp[i][j]表示区间i,j之内(也就是一棵子树)的最高加分。特殊的,dp[i][i-1]表示一棵空子树,其权值为1。

    这样的话转移方程就是dp[i][j] = max(dp[i][j],dp[i][k-1] * dp[i][k+1] + dp[k][k]),如果这个值较大发生了更新,就直接把它设置为这段区间的根节点。

    这样我们求成功求出了最大值。至于前序遍历很好办,我们递归访问就可以了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<set>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 1000005;
    const int INF = 1e9+7;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            ans *= 10;
            ans += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    
    int dp[100][100],v[100],n,root[105][105];
    
    void print(int l,int r)
    {
        if(l > r) return;
        if(l == r) 
        {
            printf("%d ",l);
            return;
        }    
        printf("%d ",root[l][r]);
        print(l,root[l][r]-1);
        print(root[l][r]+1,r);
    }
    
    int main()
    {
        n = read();
        rep(i,1,n) v[i] = read();
        rep(i,1,n) dp[i][i] = v[i],dp[i][i-1] = 1;
        per(i,n,1)
        rep(j,i+1,n)
        rep(k,i,j)
        {
            if(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],root[i][j] = k;    
        }
        printf("%d
    ",dp[1][n]);
        print(1,n);
        return 0;
    }
  • 相关阅读:
    第四章
    第三章
    第二章
    实验5-2: 编制程序,输入m、n(m≥n≥0)后,计算下列表达式的值并输出。 要求将计算阶乘的运算编写作函数fact(n),函数返回值的类型为float
    作业
    多人电费
    单人电费
    圆柱体积
    圆面积
    第七章
  • 原文地址:https://www.cnblogs.com/captain1/p/9637101.html
Copyright © 2011-2022 走看看