#include <cstdio>
#include <iostream>
using namespace std;

int main() {
    int dp[20];
    dp[0] = 1;
    dp[1] = 1;
    for (int i=2; i<20; i++) {
        dp[i] = 0;
        for (int j=0; j<i; j++) {
            dp[i]+=dp[j]*dp[i-1-j];
        }
    }
    int n;
    scanf("%d",&n);
    printf("%d\n",dp[n]);
}

在本题中:

设dp(n)表示有n个结点时二叉搜索树有多少种可能,则

Ⅰ.当(左子树+根节点)结点的个数为1时,左子树为空,右子树上有n - 1个结点,右子树的二叉搜索树个数为dp(n - 1)

Ⅱ.当(左子树+根节点)结点的个数为i(1 < i < n)时,左子树有i-1个结点,右子树有n-i个结点;左子树的二叉搜索树个数为dp(i-1),右子树的二叉搜索树个数为dp(n - i);由排列组合可知此时二叉搜索树总的个数为dp(i - 1) * dp(n - i)

Ⅲ.当(左子树+根节点)结点的个数为n时,右子树为空,左子树上有n - 1个结点,左子树的二叉搜索树个数为dp(n - 1)

所以,n个结点二叉搜索树的个数上述三个步骤的和。

递推公式:

dp(n)=dp(0)*dp(n-1)+dp(1)*dp(n-2)+dp(2)*dp(n-3)+…+dp(n-1)*dp(0)