9D - How many trees?

原题链接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;
}
上一篇:豪华版点名器


下一篇:【真题】CSP-S 2019 Solution