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); }