题意:给你n和h,问有多少棵n个节点高度为h的二叉搜索树(标号为1-n,只有一个节点的树高为0),答案对10^9+7取模。
思路:设dp[ n ][ h ]为 n 个节点高度不超过 h 的二叉搜索树的个数。那么dpn,h=∑i=0n-1dpi,h?1?dpn?i-1,h?1
即选定一个点,枚举左子树的个数问为 i ,剩余右子树的个数即为n - 1 - i 。详见代码:
/********************************************************* file name: spoj8549.cpp author : kereo create time: 2014年12月05日 星期五 22时45分10秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=500+50; const int MAXN=100000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=1000000000+7; #define L(x) (x<<1) #define R(x) (x<<1|1) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n,m; ll dp[N][N]; ll dfs(int n,int m){ if(m<0) return 0; if(dp[n][m]!=-1) return dp[n][m]; dp[n][m]=0; if(n == 0){ dp[n][m]=1; return dp[n][m]; } for(int i=0;i<=n-1;i++){ dp[n][m]+=dfs(i,m-1)*dfs(n-1-i,m-1); if(dp[n][m]>=mod) dp[n][m]%=mod; } return dp[n][m]; } int main(){ int T; scanf("%d",&T); memset(dp,-1,sizeof(dp)); while(T--){ scanf("%d%d",&n,&m); m++; printf("%lld\n",(dfs(n,m)-dfs(n,m-1)+mod)%mod); } return 0; }
时间: 2024-11-02 18:21:30