大家一起来数二叉树吧 简单dp
大家一起来数二叉树吧
https://ac.nowcoder.com/acm/problem/13593
题意: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; }