CF9D How many trees? 题解

题意:用n个点组成二叉树,问高度大于等于h的有多少个。

显然从外围推比较麻烦,考虑先求出小于某深度的二叉树个数然后用总数减去.对于某一深度,固定节点数,可以将结点向左右子树分割,由于二叉树左右儿子有区别,所以不会重复计数.对于每个深度都可以从上一深度转移过来,原因在于k深度可以在一个根节点上由k-1深度的两个数拼在一个二叉树上得出,由于二叉树可以为空,注意0个结点时的初始化.转移比较显然,注意先枚举j,原因如上.

\[dp_{i,j}=\sum_{k=0}^{i-1}dp_{k,j-1}*dp_{i-k-1,j-1} \]

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 36;
int n, h;
long long dp[N][N];
int main()
{
    cin >> n >> h;
    for (int i = 0; i <= n; i++)
        dp[0][i] = 1;
    for (int i = 1; i <= n; i++)     //depth,由于结点数会串行,深度线性递推而先枚举深度
        for (int j = 1; j <= n; j++) //tot
            for (int k = 0; k < j; k++)
                dp[j][i] += dp[k][i - 1] * dp[j - k - 1][i - 1]; //根节点还占一个位置
    cout << dp[n][n] - dp[n][h - 1] << endl;
    return 0;
}
posted @ 2021-11-05 22:04  Kinuhata  阅读(36)  评论(0)    收藏  举报