1. 程式人生 > >WannaflyCamp 平衡二叉樹(DP)題解

WannaflyCamp 平衡二叉樹(DP)題解

樹的高度 給定 color 平衡 一個 情況 來源 bject scanf

鏈接:https://www.nowcoder.com/acm/contest/202/F
來源:牛客網

題目描述

平衡二叉樹,顧名思義就是一棵“平衡”的二叉樹。在這道題中,“平衡”的定義為,對於樹中任意一個節點,都滿足左右子樹的高度差不超過 d. 空樹的高度定義為0,單個節點的高度為1,其他情況下樹的高度定義為根節點左右子樹高度最大值 + 1. 一棵在高度上平衡的樹,節點數可能不平衡,因此再定義一棵樹的不平衡度為這棵樹中所有節點的左右子樹的節點數之差的最大值。
給定平衡的定義參數d, 你需要求出所有高度為 n 的平衡樹中不平衡度的最大值。

輸入描述:

兩個整數,n, d.

輸出描述:

一個整數:所有高度為 n 的平衡樹中不平衡度的最大值。
示例1

輸入

4 1

輸出

5

思路:顯然選擇根節點差最大。顯然左樹是滿二叉樹。那麽要保證右樹最小。我們用dp[i]表示深度為i的最小平衡樹結點數,一棵樹的左右子樹深度差d,假如深度為n,那麽左樹是dp[n - 1],右樹是dp[n - 1 - d]。

代碼:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include
<cstring> #include<iostream> #include<algorithm> typedef long long ll; const int maxn = 5000 + 10; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; ll dp[100]; int main(){ ll n, d; scanf("%lld%lld", &n, &d); if(n == 0){ printf(
"0\n"); } else{ for(int i = 0; i <= d; i++) dp[i] = i; for(int i = d + 1; i <= n - 1 - d; i++){ dp[i] = dp[i - 1] + dp[i - 1 - d] + 1; } ll l = (1LL << (n - 1)) - 1, r = dp[n - 1 - d]; printf("%lld\n", l - r); } return 0; }

WannaflyCamp 平衡二叉樹(DP)題解