「BZOJ3769」「SPOJ 8549 BST again
Description
求有多少棵大小为n的深度为h的二叉树。(树根深度为0;左右子树有别;答案对1000000007取模)
Input
第一行一个整数T,表示数据组数。
以下T行,每行2个整数n和h。
Output
共T行,每行一个整数表示答案(对1000000007取模)
Sample Input
2
2 1
3 2
2 1
3 2
Sample Output
2
4
4
HINT
对于100%的数据,1<=n<=600,0<=h<=600,1<=T<=10
题解
f[i][j]表示大小i,深度小于j的二叉树数量
则
f[i][j]=(1<=k<=i)Σf[k-1][j-1]*f[i-k][j-1]
。。。理论上好像是n^3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include<map> #include<set> #include<cmath> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define ll long long #define mod 1000000007 #define inf 1000000000 using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int T,n,h; int f[605][605]; int dp(int x,int y) { if(!x)return 1; if(!y)return x==1; int &res=f[x][y]; if(res!=-1)return res; res=0; for(int i=1;i<=x;i++) { res+=(ll)dp(i-1,y-1)*dp(x-i,y-1)%mod; res%=mod; } return res; } int main() { memset(f,-1,sizeof(f)); T=read(); while(T--) { n=read();h=read(); int ans; if(h==0)ans=dp(n,h); else ans=(dp(n,h)-dp(n,h-1)+mod)%mod; printf("%d\n",ans); } return 0; } |
Subscribe