DestinHistoire

 

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)    收藏  举报

导航