51nod_1412_AVL树的种类_动态规划

51nod_1412_AVL树的种类_动态规划

题意:

平衡二叉树(AVL树),是指左右子树高度差至多为1的二叉树,并且该树的左右两个子树也均为AVL树。 现在问题来了,给定AVL树的节点个数n,求有多少种形态的AVL树恰好有n个节点。

 

分析:

把一个AVL树拆成根节点,左子树和右子树。

左子树和右子树的情况只有两种:高度相等或者高度差1。

设f[i][j]表示i个结点,高度为j的AVL树的个数。

转移:f[i][j]+=f[k][j-1]*f[i-k-1][j-1]+2*f[k][j-2]*f[i-k-1][j-1]

 

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <bitset>
using namespace std;
#define LL long long
LL p=1000000007;
LL f[2020][20],g[20],n;
int main(){
	scanf("%lld",&n);
	int i,j,k;
	f[0][0]=1;
	f[1][1]=1;
	for(i=2;i<=n;i++){
		for(k=2;k<16;k++){
			for(j=0;j<i;j++){
				f[i][k]=(f[i][k]+f[j][k-1]*f[i-j-1][k-1])%p;
				f[i][k]=(f[i][k]+2*f[j][k-2]*f[i-j-1][k-1])%p;
			}
		}
	}
	LL ans=0;
	for(i=1;i<16;i++) ans=(ans+f[n][i])%p;
	printf("%lld\n",ans);
}

 

posted @ 2018-03-10 11:03  fcwww  阅读(243)  评论(0编辑  收藏  举报