728x90
개요
문제 링크
골드 5, DP
왼쪽, 오른쪽의 subtree의 높이차가 1 이하인 binary tree의 최대 높이
접근
- 재귀적 성질을 잘 활용하면 되는 문제, 난 AVL tree가 뭔지 모른다. 그만큼 몰라도 충분히 풀 수 있다.
- 높이가 k인 트리를 생각하자. 이 트리의 높이가 균형을 이루려면 왼쪽, 오른쪽 subtree가 균형을 이루어야 한다. 그런데 그리디하게 생각해서, 가장 높은 트리를 만들려면 왼쪽과 오른쪽 트리의 높이가 1차이 나는 것이 좋다.
- 왼쪽이 높다고 가정하면, 높이가 k인 트리의 왼쪽 subtree는 k-1 균형트리, 오른쪽 subtree는 k-2균형 트리가 된다.
- 이제 dp를 사용해보자. dp[k]를 높이가 k인 트리를 만드는데에 필요한 최소 정점수 라고 하자. 그럼 왼쪽에는 k-1 균형트리, 오른쪽에는 k-2 균형트리가 있으니 dp[k] = dp[k-1]+dp[k-2]가 되고, 둘을 이어줄 정점이 하나 필요하므로 +1을 해주면 된다.
- 아하 피보나치랑 유사한 문제였구나. 이제 n에 대해 가장 정점이 많이 필요한 높이부터, 정점의 개수가 n보다 작거나 같아지면, 즉 n개로 높이 k인 트리를 구성할 수 있으면 k를 출력하면 된다.
Pseudo code
dp[n] = V needed for tree with height k
dp[1] = 1, dp[2] = 2
for (i = 3~n)
dp[i] = dp[i-1]+dp[i-2]+1
for (i = n~1)
if (dp[i] <= n)
return i
Source code
#include <iostream>
using namespace std;
#define F 43
int fib[F];
int test() {
int n;
cin >> n;
for (int i=F-1; i; i--)
if (fib[i] <= n)
return i;
return -1;
}
int main() {
fib[1] = 1, fib[2] = 2;
for (int i=3; i<F; i++)
fib[i] = fib[i-1]+fib[i-2]+1;
int t;
cin >> t;
while(t--)
cout << test() << "\n";
}
728x90
'백준브실골 > DP' 카테고리의 다른 글
백준 10109, Troyangles (0) | 2023.03.28 |
---|---|
백준 10978, 기숙사 재배정 (0) | 2023.02.19 |
백준 13707, 합분해 2 (0) | 2023.02.17 |
백준 5569, 출근 경로 (0) | 2023.02.17 |
백준 17856, Just Passing Through (0) | 2023.02.17 |
백준 1663, XYZ 문자열 (0) | 2023.02.17 |
백준 13910, 개업 (0) | 2023.02.17 |
백준 5549, 행성 탐사 (0) | 2023.02.17 |
댓글