• dp + 组合数 Codeforces Beta Round #9 (Div. 2 Only) D


    http://codeforces.com/problemset/problem/9/D

    题目大意:给你一个二叉树和n个数字,满足左小右大,能形成多少种不同的二叉树

    思路:定义dp[i][j]表示目前有i个节点,根节点为i,深度为j。

    然后我们就暴力枚举顶点i,然后以他为树根,再暴力一下左右两个子树就好了。

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha printf("haha
    ")
    const int maxn = 35 + 5;
    int n, H;
    LL dp[maxn][maxn];
    /*
    定义dp[i][j]表示目前结点,深度为j
    dp[i][j] = sigma(dp[i - k - 1][j - z - 1] * dp[k][z]);
    */
    
    int main(){
        cin >> n >> H;
        for (int i = 0; i <= n; i++) dp[0][i] = 1;
        for (int i = 1; i <= n; i++){
            for (int h = 1; h <= i; h++){///目前i个组成的最大层数
                for (int j = 0; j < i; j++){///left的个数
                    for (int l = 0; l <= j; l++){///left的最大层数
                        for (int r = 0; r <= i - j - 1; r++){///右边的最大层数
                            if (1 + max(l, r) == h){
                                dp[i][h] += dp[j][l] * dp[i - j - 1][r];
                            }
                        }
                    }
                }
            }
        }
        LL ans = 0;
        for (int i = H; i <= n; i++)
            ans += dp[n][i];
        printf("%lld
    ", ans);
        return 0;
    }
    View Code

    不过我貌似看到了卿学姐写的更加简单,定义的也更加简单

    http://www.cnblogs.com/qscqesze/p/5414271.html

    定义dp[i][j]表示目前深度小于等于i,有j个节点的所有二叉树的种类数,然后容斥一下就好了

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha printf("haha
    ")
    const int maxn = 35 + 5;
    int n, H;
    LL dp[maxn][maxn];
    /*
    定义dp[i][j]表示目前深度小于等于i,有j个节点的所有二叉树的种类数
    dp[i][j] = sigma(dp[i - 1][j - k - 1] * dp[i - 1][j - k]);
    */
    
    int main(){
        cin >> n >> H;
        for (int i = 0; i <= n; i++) {///目前深度为i
            dp[i][0] = 1;
            for (int j = 1; j <= n; j++){///总节点数
                for (int k = 0; k < j; k++){///左边节点的个数
                    dp[i][j] += dp[i - 1][k] * dp[i - 1][j - k - 1];
                }
            }
        }
        printf("%lld
    ", dp[n][n] - dp[H - 1][n]);
        return 0;
    }
    View Code
  • 相关阅读:
    JSP介绍
    Cookie和Session的原理及异同
    过滤器的使用
    JAVA 集合
    **JVM** 类加载机制
    *JAVA IO/NIO*
    jvm
    ioc
    spring问题总结
    aop详解
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5993096.html
Copyright © 2020-2023  润新知