#9 (Div. 2 Only) D. How many trees? (dp)(好题)

题目链接:

点击打开链接

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

题意:

规定一个二叉树,有n个节点,问你深度大于等于h的一共有多少种?这个二叉树满足左儿子比自己小,右儿子比自己大的特性。

题解:

dp。

假设dp[ i ][ j ]表示当前用了 i 个节点,深度度小于等于 j 的方案数。

如果我们直接求深度大于等于h有点难。那么我们就求深度小于等于h的。那么,n个节点高度小于等于n的树的种数,减去,n个节点高度小于等于h-1的种数,这就是我们要求的方案数。

假设节点数n和高度h。那么节点数为n,高度为h的树的种数是怎么得到的?答案是通过两棵子树(高度减一)的种数的乘积得到的。

那么,我们容易得到转移方程:

dp[ n ][ k ] += dp[ i ] [ k - 1] * dp[ n - i - 1 ][ k-1 ] , 其中k是高度,n是节点数,i是左儿子的节点数,n - i - 1 是右儿子的节点数。

显然要枚举高度 k,节点数n,还有左儿子节点数或者右儿子节点数。


AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[40][40];
//n个节点高度小于等于n的树的种数-n个节点高度小于等于h-1的种数
int main()
{
	int n,h;
	cin>>n>>h;
	for(int i=1;i<=n;i++)//高度 
	{  
		dp[0][i-1] = 1;
		for(int j=1;j<=n;j++)//拿n个节点
		{
			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;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值