链接:https://www.nowcoder.com/acm/contest/202/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld
题目描述
平衡二叉树,顾名思义就是一棵“平衡”的二叉树。在这道题中,“平衡”的定义为,对于树中任意一个节点,都满足左右子树的高度差不超过 d. 空树的高度定义为0,单个节点的高度为1,其他情况下树的高度定义为根节点左右子树高度最大值 + 1. 一棵在高度上平衡的树,节点数可能不平衡,因此再定义一棵树的不平衡度为这棵树中所有节点的左右子树的节点数之差的最大值。
给定平衡的定义参数d, 你需要求出所有高度为 n 的平衡树中不平衡度的最大值。
输入描述:
两个整数,n, d.
输出描述:
一个整数:所有高度为 n 的平衡树中不平衡度的最大值。
示例1
输入
4 1
输出
5
说明
下面这棵树在 d=1 的定义下高度是平衡的,其不平衡度为 5。
备注:
0 ≤ n, d ≤ 60
题解:假设左子树大于右子树,则左子树一定为高度为n – 1的满二叉树,而右子树为高度为 n – 1 – d 的最小平衡二叉树。最小平衡二叉树有个递推公式
当高度为h,高度差不超过d的最小平衡二叉树结点个数:
f(h) = h (h <= d)
f(h) = f(h – 1) + f(h – d – 1) (h > d)
高度为h的满二叉树的结点个数:
f(h) = 2^(h – 1) – 1;
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 65;
long long dp[maxn],n,d;
int main()
{
scanf("%lld %lld",&n,&d);
memset(dp,0,sizeof(dp));
for(int i = 1;i <= n - 1 - d;i++)
{
if(i > d) dp[i] = dp[i - 1] + dp[i - d - 1] + 1;
else dp[i] = (long long)i;
}
long long ans = 0;
ans = ((long long)1 << (n - 1)) - 1 - dp[max(n - 1 - d,(long long)0)];
printf("%lld\n",ans);
return 0;
}