【BZOJ 3769】【spoj 8549】BST again

問題描述

求有多少棵大小爲n的深度爲h的二叉樹。(樹根深度爲0;左右子樹有別;答案對1000000007取模)spa

輸入格式

第一行一個整數T,表示數據組數。 如下T行,每行2個整數n和h。code

輸出格式

共T行,每行一個整數表示答案(對1000000007取模)blog

樣例輸入

2 io

2 1 class

3 2原理

樣例輸出

2二叉樹

4搜索

數據範圍

對於100%的數據,1≤n≤600,0≤h≤600,1≤T≤10數據

題解

f[i][j]表示大小爲i,深度不超過j的樹的個數di

除去根節點,子樹中還有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 }
相關文章
相關標籤/搜索