[c++] BOJ 12888 :: μ™„μ „ 이진 트리 λ„λ‘œ λ„€νŠΈμ›Œν¬

문제

μ™„μ „ 이진 트리 λ„λ‘œ λ„€νŠΈμ›Œν¬ 문제 λ°”λ‘œκ°€κΈ°

BOJ λ‚˜λΌλŠ” λ„μ‹œμ™€ 두 λ„μ‹œλ₯Ό μ—°κ²°ν•˜λŠ” λ„λ‘œλ‘œ 이루어져 μžˆλ‹€. 이 λ‚˜λΌμ˜ λ„λ‘œ λ„€νŠΈμ›Œν¬λŠ” μ™„μ „ 이진 트리의 ν˜•νƒœλ₯Ό 가진닀.

μˆ˜λΉˆμ΄λŠ” BOJ λ‚˜λΌμ˜ λ„λ‘œ λ„€νŠΈμ›Œν¬ 트리의 높이 Hλ₯Ό μ•Œκ³  μžˆλ‹€. 트리의 높이λ₯Ό μ•ˆλ‹€λ©΄, λ„μ‹œμ˜ κ°œμˆ˜μ™€ λ„λ‘œμ˜ κ°œμˆ˜λ„ ꡬ할 수 μžˆλ‹€. 트리의 높이가 H인 κ²½μš°μ— λ„μ‹œμ˜ κ°œμˆ˜λŠ” 2(H+1)-1개 이고, λ„λ‘œμ˜ κ°œμˆ˜λŠ” 2(H+1)-2κ°œκ°€ λœλ‹€.

μ•„λž˜ 그림은 H = 2일 λ•Œ, 그림이닀.

img

μˆ˜λΉˆμ΄λŠ” λ„λ‘œ λ„€νŠΈμ›Œν¬μ— μ°¨λ₯Ό 보내렀고 ν•œλ‹€. λͺ¨λ“  μ°¨λŠ” μ‹œμž‘ λ„μ‹œμ™€ 도착 λ„μ‹œκ°€ 있으며, 같은 λ„μ‹œλ₯Ό 두 번 이상 λ°©λ¬Έν•˜μ§€ μ•ŠλŠ”λ‹€. 차의 μ‹œμž‘ λ„μ‹œμ™€ 도착 λ„μ‹œκ°€ 같을 μˆ˜λ„ μžˆλ‹€.

λͺ¨λ“  λ„μ‹œλ₯Ό λ°©λ¬Έν•œ 차의 κ°œμˆ˜κ°€ λͺ¨λ‘ 1κ°œκ°€ 되기 μœ„ν•΄μ„œ, μˆ˜λΉˆμ΄κ°€ μ°¨λ₯Ό μ΅œμ†Œ λͺ‡ λŒ€λ₯Ό 보내야 ν•˜λŠ”μ§€ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

풀이

 

μœ„μ™€ 같은 νŠΈλ¦¬κ°€ μžˆμ„ λ•Œ, ν•΄λ‹Ή λ¬Έμ œλŠ” μ–΄λ–€ μ ν™”μ‹μœΌλ‘œ 이루어져 μžˆμ„κΉŒ?

첫번째 방법은 ν•œ μžλ™μ°¨κ°€ 루트λ₯Ό κ°€λ‘œμ§€λ₯΄λŠ” κ°€μž₯ κΈ΄ 길이의 λ„λ‘œλ₯Ό κ°€λŠ” 것이닀.

h λ†’μ΄μ˜ νŠΈλ¦¬μ—μ„œ 문제의 닡을 T(h)λΌλŠ” μˆ˜μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€κ³  κ°€μ •ν•˜μž. μ΄λ ‡κ²Œ 되면 빨간색과 주황색은 항상 ν•„μš”ν•œ 차의 κ°œμˆ˜μ΄λ―€λ‘œ 3개λ₯Ό 기본으둜 ν•˜κ³ , T(h-2)λΆ€ν„° T(1)κΉŒμ§€ 2λ₯Ό κ³±ν•˜λ©΄μ„œ 계속 더해주면 λœλ‹€.

ν•˜μ§€λ§Œ hκ°€ 높아감에 λ”°λΌμ„œ μ™„μ „ 이진 νŠΈλ¦¬μ΄λ―€λ‘œ λ˜‘κ°™μ€ κ·œμΉ™μ΄ 반볡되고, 이λ₯Ό μ ν™”μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλŠ”λ° T(i) = T(i-1) + T(i-2)*2이닀.

 

 

두 λ²ˆμ§Έλ‘œλŠ” μœ„μ˜ ν•œ νŠΈλ¦¬μ™€ μ•„λž˜μ˜ 두 트리둜 λ‚˜λˆ„λŠ” 방법이닀.

μ΄λ ‡κ²Œ λ‚˜νƒ€λ‚΄μ—ˆμ„ λ•Œ jλ₯Ό λΉ¨κ°„μƒ‰μœΌλ‘œ ν‘œμ‹œν•œ 트리의 h라고 μƒκ°ν•΄λ³΄μž. jλŠ” i-jκ°€ 1이 될 λ•ŒκΉŒμ§€ 즉, μ•„λž˜μ˜ 주황색 트리 높이가 1이 될 λ•ŒκΉŒμ§€ μ§„ν–‰λ˜λ©°, μ‹œμž‘μ€ 빨간색 νŠΈλ¦¬κ°€ 0일 λ•ŒλΆ€ν„° μ‹œμž‘ν•œλ‹€.

점화식은 λ‹€μŒκ³Ό κ°™λ‹€.

 

λ”°λΌμ„œ ν•΄λ‹Ή λ¬Έμ œλŠ” 첫번째 방법과 λ‘λ²ˆμ§Έ 방법을 λͺ¨λ‘ μ‹œν–‰ν•˜λ©΄μ„œ κ°€μž₯ μž‘μ€ 값을 μ°Ύμ•„λ‚΄λ©΄ λœλ‹€. μž…λ ₯ 값이 적을 λ•ŒλŠ” 첫번째 방법이 무쑰건 정닡인 κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ, μž…λ ₯ 값이 μ»€μ§€κ²Œ 되면 그렇지 μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

λ˜ν•œ, λ‘λ²ˆμ§Έ 방법은 트리의 λ†’μ΄λ§ŒνΌ 진행해야 ν•˜κ³  λͺ¨λ“  λ†’μ΄μ˜ νŠΈλ¦¬μ— λŒ€ν•΄ 정닡을 미리 κ΅¬ν•΄λ†“μœΌλ―€λ‘œ O(n^2)μ΄μ§€λ§Œ 높이가 60이 μ΅œλŒ€μ΄λ―€λ‘œ μΆ©λΆ„ν•˜λ‹€.

 

μ½”λ“œ

#include <iostream>
#include <math.h>

using namespace std;


int main() {
    long long powArr[61];
    for (int i = 1; i < 61; i++) {
        powArr[i] = pow(2, i);
    }

    long long result[61] = { 1,1,3 };

    for (int i = 3; i < 61; i++) {
        result[i] = result[i - 1] + result[i - 2] * 2;
        for (int j = 1; i-j > 0; j++) {
            long long tmp = result[j - 1] + result[i - j] * powArr[j];
            if (tmp < result[i])
                result[i] = tmp;
        }
    }

    int h; cin >> h;
    cout << result[h];
}

 

κ°œμ„ 

  • 두 번째 방법은 반볡적인 νŒ¨ν„΄μ΄ λ‚˜νƒ€λ‚˜κΈ° λ•Œλ¬Έμ— μ‹œκ°„μ„ 쀄일 μˆ˜λ„ μžˆκ² μ§€λ§Œ, μ‹œκ°„μ΄ 이미 0ms이기 λ•Œλ¬Έμ— λ”±νžˆ 쀄이지 μ•Šμ•„λ„ 될 것 κ°™λ‹€.
  • μž…λ ₯을 λ¨Όμ € λ°›κ³  μž…λ ₯κΉŒμ§€μ˜ result λ°°μ—΄λ§Œ μ±„μš°λŠ” 것도 μ‹œκ°„μ„ 쀄일 수 μžˆλ‹€.

 

κ²°κ³Ό

아이디 λ©”λͺ¨λ¦¬ μ‹œκ°„ μ½”λ“œ 길이
gmldms784 2208 0 730
λ°˜μ‘ν˜•