【BZOJ 3769】【spoj 8549】BST again

问题描述

求有多少棵大小为n的深度为h的二叉树。(树根深度为0;左右子树有别;答案对1000000007取模)

输入格式

第一行一个整数T,表示数据组数。 以下T行,每行2个整数n和h。

输出格式

共T行,每行一个整数表示答案(对1000000007取模)

样例输入

2

2 1

3 2

样例输出

2

4

数据范围

对于100%的数据,1≤n≤600,0≤h≤600,1≤T≤10

题解

f[i][j]表示大小为i,深度不超过j的树的个数

除去根节点,子树中还有i-1个节点,枚举左右子树的节点数,乘法原理相乘

f[i][j]=f[i-k-1][j-1]+f[k][j-1] (0≤k<i)

边界条件,当i==0时,由于乘法的需要,f[0][j]=1;当j==0时,当且仅当i==1时存在一个二叉树,f[i][0]=(i==1)

如果用记忆化搜索,i==0的条件必须写在j==0前面,因为j==0的条件后还有i==1的条件,不满足这个条件,还有i≠0的条件,包含了i==0的条件(有点绕?)

 

 1 #include <cstdio>
 2 const int maxn=1000000007;
 3 int T,n,h,f[605][605],ans;
 4 int dp(int i,int j)  
 5 {
 6     if (i==0) return 1;
 7     if (j==0) return i==1;
 8     if (f[i][j]) return f[i][j]; 
 9     for (int k=0;k<i;k++)
10       f[i][j]=(f[i][j]+1ll*dp(i-k-1,j-1)*dp(k,j-1)%maxn)%maxn; 
11     return f[i][j];
12 } 
13 int main()
14 {
15     int i,j,k;
16     scanf("%d",&T);
17     while (T--)
18     {
19         scanf("%d%d",&n,&h);
20         ans=dp(n,h)-dp(n,h-1);
21         while (ans<0) ans+=maxn;
22         printf("%d\n",ans);
23     }
24     return 0;
25 }

 

转载于:https://www.cnblogs.com/rabbit1103/p/9881278.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值