原题链接https://codeforces.com/problemset/problem/8/C
这题自己sb,后面s数组没有加够,出现了空值,调了老半天,我是sb。
题意:
给你n个结点,权值1~n,问你最多能组成多少棵深度不小于 k 的二叉搜索树。
思路:大的树是由小的树构成的,因此可以递推(DP)。详情见代码,有注释。
代码如下
int n, h;
ull ans;
ull f[N][N];// f[i][j] 表示结点数是 i ,高度是 j 的树的数目
ull s[N][N];
int main()
{
IOS;
cin >> n >> h;
f[0][0] = 1; //没有结点也认为是 1 ,毕竟可以没有一边的儿子
for(int i = 0 ; i <= n ; i ++) s[0][i] = 1;
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= i ; j ++) //从左到右枚举
{
int l = j - 1, r = i - j; //左边结点数和右边结点数
int c = max(l, r);
for(int k = 0 ; k <= c ; k ++)
{
if(l >= k && k - 1 >= 0)
f[i][k + 1] += f[l][k] * s[r][k - 1]; //左边是高度为 k,右边比这小
if(r >= k && k - 1 >= 0)
f[i][k + 1] += f[r][k] * s[l][k - 1]; //右边是高度为 k,左边比这小
if(l >= k && r >= k) //左右高度相等的情况
f[i][k + 1] += f[r][k] * f[l][k];
}
}
for(int j = 1 ; j <= n ; j ++) //一定要加到n 因为只要比这 k - 1比较大时要有数值
s[i][j] = f[i][j] + s[i][j - 1];
}
for(int i = h ; i <= n ; i ++)
ans += f[n][i];
cout << ans << endl;
return 0;
}