ALGORITHM

[ALGORITHM] Dynamic programming / 동적 κ³„νšλ²•

girin_dev 2022. 10. 13. 00:17
728x90
λ°˜μ‘ν˜•

πŸ‘Œ 동적 κ³„νšλ²•. 

 

핡심은 top down / bottom up λ°©μ‹μ—μ„œ μ€‘λ³΅λ˜λŠ” 연산을 ν”Όν•˜λŠ” 것.

-> O(2^n)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€κ²Œ 될 경우 ( μž¬κ·€ ν•¨μˆ˜ )

-> μ—°μ‚°μ˜ νšŸμˆ˜κ°€ λŠ˜μ–΄λ‚œλ‹€.

-> 콜 μŠ€νƒμ΄ 많이 λŠ˜μ–΄λ‚˜λ―€λ‘œ μ„±λŠ₯이 μ•ˆμ’‹μ•„μ§„λ‹€.

 

μ„±λŠ₯뿐만이 μ•„λ‹Œ ν•œκ³„μ κΉŒμ§€ 갈 경우 μ—λŸ¬λ„ λ°œμƒν•œλ‹€. 

 

https://loosie.tistory.com/150

 

이미 연산을 ν•œ 과정을 λ‹€μ‹œ μ—°μ‚°ν•˜λŠ” 뢀뢄이 μƒκ²¨λ‚œλ‹€.

 

 

 

 

πŸ˜” ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄λ‘œ μ˜ˆμ‹œλ₯Ό 많이 λ“ λ‹€. 

 

μ•ž + μ•žμ˜ μ•ž = λ‹€μŒ 항을 κ²°μ •

 

public class pbnc {

    public static void main(String[] args) {

        int n = 10;

    }

    // λ°˜λ³΅λ˜λŠ” 연산을 κ³ λ €ν•˜μ§€ μ•ŠμŒ.
    static int ffibo1( int x ) {
        if (x == 1 || x== 2) {
            return 1;
        }

        return ffibo1(x-1) + ffibo1(x -2);
    }
}

 

 

 

 

 

 

λ°˜λ³΅λ˜λŠ” 연산을 ν”Όν•˜κ³  μ‹Άλ‹€λ©΄, ν•œλ²ˆ μ—°μ‚°ν•œ 값은 연산없이 μ“Έ 수 있게 κΈ°μ–΅ν•˜κ³  있으면 λœλ‹€. 

 

λ”°λΌμ„œ, μ΄λ―Έ μ•žμ„œ μ—°μ‚°ν•œ 과정은 λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ 톡해 연산을 μƒλž΅ ν•  수 μžˆλ‹€. 

 

🀒 λ©”λͺ¨μ΄ μ œμ΄μ…˜ ==> μ—°μ‚°ν•œ κ²°κ³Ό ( ν•œ 번 κ³„μ‚°ν•œ κ²°κ³Ό ) λ₯Ό λ©”λͺ¨λ¦¬ 곡간에 λ©”λͺ¨ ν•˜λŠ” 것.

 

 

static int memoFibo(int x) {
    if (x == 1 || x == 2) {
        return 1;
    }

    // λ°°μ—΄ dp[x]κ°€ μ—°μ‚°ν•œ 적이 μžˆλ‹€λ©΄,
    if (dp[x] != 0) {
        return dp[x]; // μ—°μ‚° ν–ˆλ˜ κ°’ (λ©”λͺ¨μ œμ΄μ…˜ κ°’) 을 λ¦¬ν„΄ν•œλ‹€.
    }

    // μ—°μ‚° ν•œ 적이 μ—†λ‹€λ©΄ μ—°μ‚°ν•΄μ„œ λ©”λͺ¨μ œμ΄μ…˜ 처리.
    dp[x] = memoFibo(x-1) + memoFibo(x-2);
    return dp[x];
}

 

 

μœ„ 방식은 λ‹€μŒκ³Ό 같은 그림에 ν•΄λ‹Ήν•œλ‹€.

 

 

https://loosie.tistory.com/150

 

 

 

 

 

 

이런 λ©”λͺ¨μ œμ΄μ…˜μ„ κ΅¬ν˜„ν•΄μ„œ 동적 κ³„νšλ²•μ„ κ΅¬μƒν•˜λŠ” 방법은 크게 top down(μž¬κ·€)  / bottom up(for-loop) 방식이  μžˆλ‹€.

 

μž¬κ·€λŠ” μœ„μ˜ 방식과 λ™μΌν•˜λ―€λ‘œ μƒλž΅ν•˜κ³  bottom up 방식은 λ‹€μŒκ³Ό κ°™λ‹€. 

 

    static int bottomUpForLoop(int j ) {

        // 10번 μ—°μ‚°ν•˜κ³  μ‹Άλ‹€λ©΄,
        int n = 10;

        dp[0] = 1;
        dp[1] = 1;

        int k = n;

        for (int i=0; i<n; i++) {
            if (dp[i]==null) { //λ°°μ—΄ 값이 없을 경우만 μ—°μ‚°.
                dp[i]=dp[i-1]+dp[i-2];
            }
        }
       return dp[n];
    }

 

 

끝.

 

 

 

 

https://www.acmicpc.net/problem/10844

 

10844번: μ‰¬μš΄ 계단 수

첫째 쀄에 정닡을 1,000,000,000으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό 좜λ ₯ν•œλ‹€.

www.acmicpc.net

 

320x100
λ°˜μ‘ν˜•