0
点赞
收藏
分享

微信扫一扫

[动态规划]DP5 有多少个不同的二叉搜索树-中等

​​DP5 有多少个不同的二叉搜索树​​

描述

给定一个由节点值从 1 到 n 的 n 个节点。请问由多少种不同的方法用这 n 个节点构成互不相同的二叉搜索树。


数据范围: [动态规划]DP5 有多少个不同的二叉搜索树-中等_二叉搜索树

输入描述:

仅一行输入一个正整数 n ,表示节点的数量。

输出描述:

输出组成不同二叉搜索树的方法数。

示例1

输入:

3

输出:

5

示例2

输入:

2

输出:

2

题解

动态规划解法

  1. 假设dp[i]表示的是i个不同元素可以组成的二茬搜索树的方法数
  2. 初始条件:dp[0] = dp[1] = 1
  3. 递推条件:对于dp[i],我们可以依次选择从1~i的树作为根节点,假设我们选择的是节点k,且 1 <= k <= i,那么根据二叉树的性质,1~k-1的数只能放在k的左边,[k+1,i]的数只能放在根节点的右边,因此dp[i] = [动态规划]DP5 有多少个不同的二叉搜索树-中等_动态规划_02

注意:本来dp[0]按照我的理解应该是0的,但是当我们选择i(或者1)为根节点的时候,剩余的1~i-1这些数都应该放在左边组成的方法有dp[i-1],此时如果乘以dp[0] == 0,那么和我们逾期的结果不符,因此将dp[0]设置为1


代码如下:

#include <bits/stdc++.h>

int solve(int n)
{
if (n <= 0)
{
return 0;
}

std::vector<int> dp(n + 1, 0); // dp[i]表示从0或者1台阶到达i的时候的最小值
dp[0] = 1;
dp[1] = 1;

for (int i = 2; i <= n; ++i)
{
for (int k = 1; k <= i; ++k)
{
dp[i] = dp[i] + dp[k - 1] * dp[i - k];
}
}
return dp.back();
}

int main()
{
int n, x;
std::vector<int> costs;
std::cin >> n;

std::cout << solve(n) << std::endl;
return 0;
}


举报

相关推荐

0 条评论