题意:n个节点,m个叶子,问有多少种形态的二叉树
题解:二叉树的每一次延伸一个节点相当于加上一棵子树,考虑到是二叉树,所以考虑一左一右相当于*2。所以当你需要x个节点,其中有y个叶子时候,就需要考虑x个节点y个叶子拆分后分配到左右子树上,而且拆分后又变成了一个子子树,这个子子树又有它本身多种形态,所以需要乘法。
故dp核心式子是 dp[i][j]=(dp[i][j]+dp[x][y]dp[i-x-1][j-y]%mod)%mod,
中i代表的总节点数,j代表的是总叶子数,x代表的是左子树的节点数,y代表的是左子树的叶子数,而i-x-1代表的右子树的节点数(-1是取出头节点),y-代表的是左子树的叶子数。

#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
#define ll long long
#define endl "\n"
const int mod=1e9+7;
ll dp[55][55];
int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    dp[0][0]=1;dp[1][1]=1;
       for(int i=1;i<=50;i++)
           for(int j=1;j<=i;j++)
            for(int x=0;x<i;x++)
                for(int y=0;y<=j;y++)
                    dp[i][j]=(dp[i][j]+dp[x][y]*dp[i-x-1][j-y]%mod)%mod;        
    int n,m;
    while(cin>>n>>m)cout<<dp[n][m]<<endl;
    return 0;
}