11082 完全二叉树的种类

戏子无情 提交于 2020-01-10 01:55:44

11082 完全二叉树的种类
时间限制:800MS 内存限制:1000K
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC
Description
构造n个(2<=n<=20)叶结点的的完全二叉树(完全二叉树意味着每个分支结点都有2个儿子结点),有多少种构造方法?

注意:不改变n个结点的相对顺序,左右儿子不调换.

例如:
4个叶子节点A1,A2,A3,A4,可构造出如下完全二叉树,共5种。

再例如:5个叶子结点,A1,A2,A3,A4,A5,可构造出如下若干种完全二叉树形状,像这样的完全二叉树共有14种(下图
并未全部列出)。

输入格式
输入n,表示构造的完全二叉树有n个叶结点(2<=n<=20)。

输出格式
输出构造的完全二叉树的种类。

输入样例
5

输出样例
14

提示

把所有叶节点从左到右编上号:1,2,…,n。
无论怎样构造的完全二叉树,根节点左边的左子树和右边的右子树又都是完全二叉树,
那么n个节点的完全二叉树构造方法数等于左子树的构造方法数乘以右子树的构造方法数,
且要列举所有可能的左子树和右子树分布情况,而后所有情况方法数相加。假设左子树的
叶子为1,…,i。右子树的叶子就是:i+1,…,n。

设n个叶子的完全二叉树构造方法数为Total(n)。Total(n)的递归公式如下,这是Catalan数:
Total(n) = sum{ Total(i) * Total(n-i) | for i=1 to n-1 } if n>=2
Total(n)=1 if n=1

考虑到计算Total(n)时,所有小于规模n的Total(n-1),…,Total(1)都可能被计算多次,
存在大量重复计算的问题。因此比较好的方法是对i从2到n,边计算Total(i),边用表记录下来,
即备忘录的方法,时间复杂度为O(n^2)。

作者 zhengchan

Version: 2

没什么好说的,照着提示打。

#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
int n=0;
int Total(int *a);
int main()
{
    cin>>n;
    int a[n+1];
    for (int i = 0; i <=n ; i++) {
        a[i]=0;
    }
    Total(a);
}
int Total(int *a){
    a[1]=1;
    for (int i = 2; i <=n ; i++) {
        for (int k = 1; k <n ; k++) {
            a[i]+=a[k]*a[i-k];
        }
    }
    cout<<a[n];
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!