BZOJ-3769 spoj 8549 BST again(dp)
题目描述
求有多少棵大小为 \(n(1\leq n\leq 600)\) 的深度为 \(m(0\leq h\leq 600)\) 的二叉树(树根深度为 \(0\);左右子树有别;答案对 \(10^9+7\) 取模)。
分析
设 \(dp[i][j]\) 为有 \(i\) 个节点,最大深度不超过 \(j\) 的二叉树的数量。
边界条件:\(dp[1][0]=1,dp[0][j]=1\)。
在转移时枚举两棵子树的节点数,状态转移方程为:
\[dp[i][j]=\sum_{k=1}^{i}dp[k-1][j-1]\times dp[i-k][j-1]
\]
答案容斥一下即可:\(dp[n][m]-dp[n][m-1]\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=610;
long long dp[N+10][N+10];
const int mod=1e9+7;
void init()
{
dp[1][0]=1;
for(int j=0;j<=N;j++)
dp[0][j]=1;
for(int j=1;j<=N;j++)
for(int i=1;i<=N;i++)
for(int k=1;k<=i;k++)
dp[i][j]=(dp[i][j]+dp[k-1][j-1]*dp[i-k][j-1]%mod)%mod;
}
int main()
{
init();
int T;
cin>>T;
while(T--)
{
long long n,m;
cin>>n>>m;
cout<<(dp[n][m]-dp[n][m-1]+mod)%mod<<endl;
}
return 0;
}
posted on 2020-11-02 20:52 DestinHistoire 阅读(52) 评论(0) 收藏 举报
浙公网安备 33010602011771号