动态规划之一起来数二叉树
题目:
https://img-blog.csdnimg.cn/20200406144807404.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NzA5OTkw,size_16,color_FFFFFF,t_70
https://img-blog.csdnimg.cn/20200406144850651.png
思路:
因为是二叉树 根据题目可以想到是动态规划的思路来求解。
可以用二维数组来保存计算结果
如果含有i个节点,j个叶子节点的二叉树(j<=i),总形态数为a[i][j]
因为为二叉树分为左子树和右子树
设左子树为x个节点,y个叶子节点;右子树就有i-x-1个节点,j-y个叶子节点(0<=x<=i-1,0<=y<=j)
递推方程:
https://img-blog.csdnimg.cn/20200406152626413.png
初始条件:当没有节点和节点为一时也是一种状态所以
long long dp[51][51] = {}; dp[0][0] = 1; dp[1][1] = 1;
代码:
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define mod 1000000007 long long dp[51][51] = {}; int main() { int n, m,i,j,x,y; dp[0][0] = 1; dp[1][1] = 1; for ( i = 2; i <= 50; i++) for (j = 1; j <= i; j++) for ( x = 0; x <= i - 1; x++) for ( y = 0; y <= j; y++) dp[i][j] = ( dp[i][j] + dp[i - x - 1][j - y] * dp[x][y]) % mod; while (cin >> n >> m) { cout << dp[n][m] << endl; } }