dp tree count

本文介绍了一种计算特定类型二叉搜索树数量的方法,这类树的特点是每个节点的左右子树高度相差不超过1。文章提供了计算这些特定二叉搜索树数量的代码实现,并考虑了结果的取模运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Tree Count

Time Limit: 5 Sec   Memory Limit: 128 MB
Submit: 29   Solved: 14
[ Submit][ Status][ Web Board]

Description

Our superhero Carry Adder has uncovered the secret method that the evil Head Crash uses to
generate the entrance code to his fortress in Oakland. The code is always the number of distinct
binary search trees with some number of nodes, that have a specific property. To keep this code
short, he only uses the least significant nine digits.
The property is that, for each node, the height of the right subtree of that node is within one of
the height of the left subtree of that node. Here, the height of a subtree is the length of the longest
path from the root of that subtree to any leaf of that subtree. A subtree with a single node has a
height of 0, and by convention, a subtree containing no nodes is considered to have a height of −1.

Input

Input will be formatted as follows. Each test case will occur on its own line. Each line will contain
only a single integer, N, the number of nodes. The value of N will be between 1 and 1427, inclusive.

Output

Your output is one line per test case, containing only the nine-digit code (note that you must print
leading zeros).

Sample Input

1
3
6
21

Sample Output

000000001
000000001
000000004
000036900
这个真心不会,看的是标称,贴下代码
View Code
#include <iostream>
#include <iomanip>
using namespace std ;
const int MAXN = 1427 ;
const int LOGMAXN = 22 ; // log base phi of MAXN, or something in excess
long long a[MAXN+1][LOGMAXN+1] ; d[i][j]代表总的节点数是i,高度是j的平衡二叉树的个数
long long t[MAXN+1] ;
int main(int, char**) {
a[0][0] = a[1][1] =1 ;
t[0] = t[1] = 1 ;
int mind = 1 ;
for (int n=2; n<=MAXN; n++) {
long long alln = 0 ;
for (int d=mind; ; d++) {
long long s = 0 ;
int havesome = 0 ;
for (int i=0; i<n; i++) {
s += a[i][d-1] * a[n-1-i][d-1] ;
if (d > 1)
s += a[i][d-2] * a[n-1-i][d-1] +
a[i][d-1] * a[n-1-i][d-2] ;
if (s)
havesome = 1 ;
s %= 1000000000 ;
}
if (havesome == 0) {
if (d == mind)
mind++ ;
else
break ;
}
s %= 1000000000 ;
a[n][d] = s ;
alln += s ;
}
t[n] = alln % 1000000000 ;
}
int n ;
while (1) {
cin >> n ;
if (cin.fail())
break ;
cout << setfill('0') << setw(9) << t[n] << endl ;
}
}
View Code
#include <iostream>
#include <iomanip>
using namespace std ;
const int MAXN = 1427 ;
const int LOGMAXN = 22 ; // log base phi of MAXN, or something in excess
long long a[MAXN+1][LOGMAXN+1] ; d[i][j]代表总的节点数是i,高度是j的平衡二叉树的个数
long long t[MAXN+1] ;
int main(int, char**) {
a[0][0] = a[1][1] =1 ;
t[0] = t[1] = 1 ;
int mind = 1 ;
for (int n=2; n<=MAXN; n++) {
long long alln = 0 ;
for (int d=mind; ; d++) {
long long s = 0 ;
int havesome = 0 ;
for (int i=0; i<n; i++) {
s += a[i][d-1] * a[n-1-i][d-1] ;
if (d > 1)
s += a[i][d-2] * a[n-1-i][d-1] +
a[i][d-1] * a[n-1-i][d-2] ;
if (s)
havesome = 1 ;
s %= 1000000000 ;
}
if (havesome == 0) {
if (d == mind)
mind++ ;
else
break ;
}
s %= 1000000000 ;
a[n][d] = s ;
alln += s ;
}
t[n] = alln % 1000000000 ;
}
int n ;
while (1) {
cin >> n ;
if (cin.fail())
break ;
cout << setfill('0') << setw(9) << t[n] << endl ;
}
}



转载于:https://www.cnblogs.com/one--world--one--dream/archive/2012/03/31/2427145.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值