[Algorithm] Dynamic Programming

Updated:

๐Ÿ“ฃ
๋ณธ ํฌ์ŠคํŠธ๋Š” โ€˜์ด๊ฒƒ์ด ์ทจ์—…์„ ์œ„ํ•œ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋‹ค with ํŒŒ์ด์ฌโ€™์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค :)
click > (์ด์ฝ”ํ…Œ 2021) ์ด๊ฒƒ์ด ์ทจ์—…์„ ์œ„ํ•œ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋‹ค with ํŒŒ์ด์ฌ

Dynamic Programming

์ด๋ก 

์šฐ๋ฆฌ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ ์—ฐ์‚ฐ ์†๋„์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ตœ๋Œ€ํ•œ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

์–ด๋–ค ๋ฌธ์ œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์•ฝ๊ฐ„ ๋” ํ™œ์šฉํ•˜๋ฉด ์—ฐ์‚ฐ ์†๋„๋ฅผ ๋น„์•ฝ์ ์œผ๋กœ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ๋ฐฉ๋ฒ•์ด ๋ฐ”๋กœ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ (Dynamic Programming) ์ด๋‹ค. ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘๊ฒŒ ๋‚˜๋ˆ„๊ณ , ๊ฐ™์€ ๋ฌธ์ œ๋ผ๋ฉด ํ•œ ๋ฒˆ์”ฉ๋งŒ ํ’€์–ด ๋ฌธ์ œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋ฒ•์œผ๋กœ ๋™์  ๊ณ„ํš๋ฒ•์ด๋ผ๊ณ  ํ‘œํ˜„ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด๊ณผ ํŒฉํ† ๋ฆฌ์–ผ์ด ์žˆ๋‹ค. ๋‘ ์˜ˆ์‹œ ๋ชจ๋‘ ์ˆ˜์—ด์˜ ํ•ญ์„ ์ ํ™”์‹์„ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ์ „์—๋Š” ๋‘ ์˜ˆ์‹œ๋ฅผ ๋ชจ๋‘ ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ, ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด n์ด ์ปค์งˆ ์ˆ˜๋ก ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•œ๋‹ค๋Š” ๋ฌธ์ œ์ ์ด ์žˆ๋‹ค. (์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ ์•ฝ O(2^n)์ด๋‹ค.) ์ด์ฒ˜๋Ÿผ ์ ํ™”์‹์„ ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ๋งค๋ฒˆ ๊ณ„์‚ฐํ•˜๋„๋ก ํ•œ๋‹ค๋ฉด ํšจ์œจ์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ํšจ์œจ์ ์œผ๋กœ ํ•ด๊ฒฐํ•œ๋‹ค. ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋‹ค์Œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค.

  1. ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
  2. ์ž‘์€ ๋ฌธ์ œ์—์„œ ๊ตฌํ•œ ์ •๋‹ต์€ ๊ทธ๊ฒƒ์„ ํฌํ•จํ•˜๋Š” ํฐ ๋ฌธ์ œ์—์„œ๋„ ๋™์ผํ•˜๋‹ค.

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ (Memorization) ๊ธฐ๋ฒ•์ด ์žˆ๋‹ค. ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ธฐ๋ฒ•์€ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์บ์‹ฑ(Caching)์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ํ•œ ๋ฒˆ ๊ตฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅํ•ด๋‘๊ณ  ๊ฐ™์€ ์‹์„ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ”๋ชจํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค.

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

  1. ํƒ‘๋‹ค์šด (Top-Down) ๋ฐฉ์‹

    ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ๋ฌธ์ œ๋“ค์„ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ํ•˜์—ฌ ํƒ‘๋‹ค์šด ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค. ํƒ‘๋‹ค์šด ๋ฐฉ์‹์€ ํ•˜ํ–ฅ์‹์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

    ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ํƒ‘๋‹ค์šด ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ (๋ฉ”๋ชจ์ด์ œ์ด์…˜)

     # ํ•œ ๋ฒˆ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization)ํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
     d = [0] * 100
        
     # ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜(Fibonacci Function)๋ฅผ ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ (ํƒ‘๋‹ค์šด ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ)
     def fibo(x):
         # ์ข…๋ฃŒ ์กฐ๊ฑด(1 ํ˜น์€ 2์ผ ๋•Œ 1์„ ๋ฐ˜ํ™˜)
         if x == 1 or x == 2:
             return 1
         # ์ด๋ฏธ ๊ณ„์‚ฐํ•œ ์  ์žˆ๋Š” ๋ฌธ์ œ๋ผ๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
         if d[x] != 0:
             return d[x]
         # ์•„์ง ๊ณ„์‚ฐํ•˜์ง€ ์•Š์€ ๋ฌธ์ œ๋ผ๋ฉด ์ ํ™”์‹์— ๋”ฐ๋ผ์„œ ํ”ผ๋ณด๋‚˜์น˜ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
         d[x] = fibo(x - 1) + fibo(x - 2)
         return d[x]
        
     print(fibo(99))
    
  2. ๋ณดํ…€์—…(Bottom-Up) ๋ฐฉ์‹

    ๋‹จ์ˆœํžˆ ๋ฐ˜๋ณต๋ฌธ์„ ์ด์šฉํ•˜์—ฌ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ์ž‘์€ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๋‹ต์„ ๋„์ถœํ•œ๋‹ค๊ณ  ํ•˜์—ฌ ๋ณดํ…€์—…(Bottom-Up) ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค. ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํƒ‘๋‹ค์šด ๋ฐฉ์‹๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋” ์ข‹๋‹ค. ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ „ํ˜•์ ์€ ํ˜•ํƒœ๋Š” ๋ณดํ…€์—… ๋ฐฉ์‹์ด๊ณ , ๋ณดํ…€์—… ๋ฐฉ์‹์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฐ๊ณผ ์ €์žฅ์šฉ ๋ฆฌ์ŠคํŠธ๋Š” DP ํ…Œ์ด๋ธ”์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

    ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๋ณดํ…€์—… ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„

     # ์•ž์„œ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ DP ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
     d = [0] * 100
        
     # ์ฒซ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์™€ ๋‘ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜๋Š” 1
     d[1] = 1
     d[2] = 1
     n = 99
        
     # ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜(Fibonacci Function) ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๊ตฌํ˜„(๋ณดํ…€์—… ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ)
     for i in range(3, n + 1):
         d[i] = d[i - 1] + d[i - 2]
        
     print(d[n])
    

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ ํ’€์ด ๋‹จ๊ณ„

  1. ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์œ ํ˜•์ž„์„ ํŒŒ์•…ํ•˜๊ธฐ
  2. ๋ณ€์ˆ˜ ๊ฐ„ ๊ด€๊ณ„์‹ ๋งŒ๋“ค๊ธฐ(์ ํ™”์‹)
  3. ๊ตฌํ˜„ํ•˜๊ธฐ(memoization or tabulation)

์‹ค์ „ ๋ฌธ์ œ

[์‹ค์ „๋ฌธ์ œ 1] 1๋กœ ๋งŒ๋“ค๊ธฐ

# ์ •์ˆ˜ X๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ
x = int(input())

# ์•ž์„œ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ DP ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
d = [0] * 1000001

# ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Dynamic Programming) ์ง„ํ–‰(๋ณดํ…€์—…)
for i in range(2, x + 1):
    # ํ˜„์žฌ์˜ ์ˆ˜์—์„œ 1์„ ๋นผ๋Š” ๊ฒฝ์šฐ
    d[i] = d[i - 1] + 1
    # ํ˜„์žฌ์˜ ์ˆ˜๊ฐ€ 2๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ
    if i % 2 == 0:
        d[i] = min(d[i], d[i // 2] + 1)
    # ํ˜„์žฌ์˜ ์ˆ˜๊ฐ€ 3์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ
    if i % 3 == 0:
        d[i] = min(d[i], d[i // 3] + 1)
    # ํ˜„์žฌ์˜ ์ˆ˜๊ฐ€ 5๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ
    if i % 5 == 0:
        d[i] = min(d[i], d[i // 5] + 1)

print(d[x])

[์‹ค์ „๋ฌธ์ œ 2] ๊ฐœ๋ฏธ ์ „์‚ฌ

# ์ •์ˆ˜ N์„ ์ž…๋ ฅ ๋ฐ›๊ธฐ
n = int(input())
# ๋ชจ๋“  ์‹๋Ÿ‰ ์ •๋ณด ์ž…๋ ฅ ๋ฐ›๊ธฐ
array = list(map(int, input().split()))

# ์•ž์„œ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ DP ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
d = [0] * 100

# ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Dynamic Programming) ์ง„ํ–‰ (๋ณดํ…€์—…)
d[0] = array[0]
d[1] = max(array[0], array[1]) 
for i in range(2, n):
    d[i] = max(d[i - 1], d[i - 2] + array[i])

# ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
print(d[n - 1])

[์‹ค์ „๋ฌธ์ œ 3] ๋ฐ”๋‹ฅ ๊ณต์‚ฌ

# ์ •์ˆ˜ N์„ ์ž…๋ ฅ ๋ฐ›๊ธฐ
n = int(input())

# ์•ž์„œ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ DP ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
d = [0] * 1001

# ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Dynamic Programming) ์ง„ํ–‰ (๋ณดํ…€์—…)
d[1] = 1
d[2] = 3
for i in range(3, n + 1):
    d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796

# ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
print(d[n])

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ