๐ŸŒฑ → ๐ŸŒณ

Algorithm) Dynamic Programming ๋ณธ๋ฌธ

Algorithms

Algorithm) Dynamic Programming

BAY 2022. 10. 25. 15:07
728x90

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ( ๋™์  ๊ณ„ํš๋ฒ•)

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ ์‹œ๊ฐ„ ํšจ์œจ์„ฑ์„ ๋น„์•ฝ์ ์œผ๋กœ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•

์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ(์ž‘์€ ๋ฌธ์ œ)๋Š” ๋ณ„๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ์ €์žฅํ•˜์—ฌ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋„๋ก ํ•จ 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ตฌํ˜„์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹ 

  • ํƒ‘ ๋‹ค์šด(ํ•˜ํ–ฅ์‹)
  • ๋ณดํ…€ ์—…(์ƒํ–ฅ์‹)

 

์ผ๋ฐ˜์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ถ„์•ผ์—์„œ ๋™์ (dynamic)์ด๋ž€?

  • ์ž๋ฃŒ๊ตฌ์กฐ์—์„œ ๋™์  ํ• ๋‹น(dynamic allocation)์€ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๋„์ค‘์— ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ธฐ๋ฒ•์„ ์˜๋ฏธ
  • ๋ฐ˜๋ฉด ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ‘๋‹ค์ด๋‚˜๋ฏน’์€ ๋ณ„ ์˜๋ฏธ ์—†์ด ์‚ฌ์šฉ๋œ ๋‹จ์–ด

 

๋‹ค์ด๋‚˜๋ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์กฐ๊ฑด 

  1. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ(Optimal Substructure)
    • ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž‘์€ ๋ฌธ์ œ์˜ ๋‹ต์„ ๋ชจ์•„์„œ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์Œ
  2. ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ (Overlapping Subproblem)
    • ๋™์ผํ•œ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ•ด๊ฒฐ

 

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ํšจ๊ณผ์ ์œผ๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Œ

1, 1, 2, 3 , 5 , 8, 13, 21, 34 ,55, …

์ ํ™”์‹ : ์ธ์ ‘ํ•œ ํ•ญ๋“ค ์‚ฌ์ด์˜ ๊ด€๊ณ„์‹

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ์ ํ™”์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Œ

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ์ ํ™”์‹

 

๋‹จ์ˆœ ์žฌ๊ท€๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ํ•ด๊ฒฐ 

def fibo(x):
    if x == 1 or x ==2:
        return 1
    return fibo(x-1) + fibo(x-2)
print(fibo(4)) # 3

 

๋‹จ์ˆœ ์žฌ๊ท€์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„ ๋ถ„์„ 

- ๋‹จ์ˆœ ์žฌ๊ท€ ํ•จ์ˆ˜๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ํ•ด๊ฒฐํ•˜๋ฉด ์ง€์ˆ˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง
- f(n)์ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ ํ™•์ธ(์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ)

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์˜ ํšจ์œจ์ ์ธ ํ•ด๋ฒ• : ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์‚ฌ์šฉ ์กฐ๊ฑด ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธ

  1. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ: ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค
    • f(4)๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด f(3), f(2)๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ
  2. ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ: ๋™์ผํ•œ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ•ด๊ฒฐ
    • f(n)์ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ ๋˜๋Š” ๊ฒƒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

→ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์€ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์‚ฌ์šฉ ์กฐ๊ฑด ๋งŒ์กฑ

 

๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)

๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜

ํ•œ ๋ฒˆ ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ๋ฉ”๋ชจํ•˜๋Š” ๊ธฐ๋ฒ•

๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ”๋ชจํ–ˆ๋˜ ๊ฒฐ๊ณผ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์˜ด

๊ฐ’์„ ๊ธฐ๋กํ•ด ๋†“๋Š”๋‹ค๋Š” ์ ์—์„œ ์บ์‹ฑ(cashing)์ด๋ผ๊ณ ๋„ ํ•จ

 

ํƒ‘๋‹ค์šด vs ๋ณดํ…€์—…

ํƒ‘๋‹ค์šด(๋ฉ”๋ชจ์ด์ œ์ด์…˜) ๋ฐฉ์‹์€ ํ•˜ํ–ฅ์‹์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ ๋ณดํ…€์—… ๋ฐฉ์‹์€ ์ƒํ–ฅ์‹์ด๋ผ๊ณ ๋„ ํ•จ

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ „ํ˜•์ ์ธ ํ˜•ํƒœ๋Š” ๋ณดํ…€์—… ๋ฐฉ์‹

๊ฒฐ๊ณผ ์ €์žฅ์šฉ ๋ฆฌ์ŠคํŠธ๋Š” DP ํ…Œ์ด๋ธ”์ด๋ผ๊ณ  ๋ถ€๋ฆ„

์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์ด์ „์— ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ๊ธฐ๋กํ•ด ๋†“๋Š” ๋„“์€ ๊ฐœ๋…

  • ๋”ฐ๋ผ์„œ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๊ตญํ•œ๋œ ๊ฐœ๋…์€ ์•„๋‹˜
  • ํ•œ ๋ฒˆ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์•„ ๋†“๊ธฐ๋งŒ ํ•˜๊ณ  ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•ด ํ™œ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ

 

ํƒ‘๋‹ค์šด ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ 

๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ํ•จ์ˆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” $O(N)$

# ํ•œ ๋ฒˆ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ memoizationํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
d = [0]* 100

# ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„(ํƒ‘๋‹ค์šด)
def fibo(x):
    print('f(' + str(x) + ')', end=' ')
    # ์ข…๋ฃŒ ์กฐ๊ฑด
    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(6))
f(6) f(5) f(4) f(3) f(2) f(1) f(2) f(3) f(4) 8

 

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

์ž‘์€ ๋ฌธ์ œ๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌํ•˜๊ณ  ์ž‘์€ ๋ฌธ์ œ๋ฅผ ํ† ๋Œ€๋กœ ์•ž์œผ๋กœ์˜ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•จ

d = [0]*100
d[1]=1
d[2]=1
n = 99
for i in range(3, n+1):
    d[i]=d[i-1]+d[i-2]
print(d[n]) # 218922995834555169026

 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ vs ๋ถ„ํ•  ์ •๋ณต

๊ณตํ†ต์  :

์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž‘์€ ๋ฌธ์ œ์˜ ๋‹ต์„ ๋ชจ์•„ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ

์ฐจ์ด์  : ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ค‘๋ณต

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ๊ฐ ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์ด ์„œ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋ฉฐ ๋ถ€๋ถ„ ๋ฌธ์ œ ์ค‘๋ณต

๋ถ„ํ•  ์ •๋ณต : ๋™์ผํ•œ ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ณ„์‚ฐ๋˜์ง€ ์•Š์Œ

 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•

์ฃผ์–ด์ง„ ๋ฌธ์ œ๊ฐ€ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์œ ํ˜•์ž„์„ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š” 

๊ฐ€์žฅ ๋จผ์ € ๊ทธ๋ฆฌ๋””, ๊ตฌํ˜„, ์™„์ „ ํƒ์ƒ‰ ๋“ฑ์˜ ์•„์ด๋””์–ด๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€ํ† 

-> ๋‹ค๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ’€์ด ๋ฐฉ๋ฒ•์ด ๋– ์˜ค๋ฅด์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ณ ๋ ค 

์ผ๋‹จ ์žฌ๊ท€ ํ•จ์ˆ˜๋กœ ๋น„ํšจ์œจ์ ์ธ ์™„์ „ ํƒ์ƒ‰ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•œ ๋’ค์–ด(ํƒ๋‹ค์šด)์ž‘์€ ๋ฌธ์ œ์—์„œ ๊ตฌํ•œ ๋‹ต์ด ํฐ ๋ฌธ์ œ์—์„œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉด, ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ 

์ผ๋ฐ˜์ ์ธ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ˆ˜์ค€์—์„œ๋Š” ๊ธฐ๋ณธ ์œ ํ˜•์˜ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ๊ฐ€ ์ถœ์ œ๋˜๋Š” ๊ฒฝ์šฐ ๋งŽ์Œ

 

์˜ˆ์ œ 1) ๊ฐœ๋ฏธ ์ „์‚ฌ

๊ฐœ๋ฏธ ์ „์‚ฌ: ๋ฌธ์ œ ํ•ด๊ฒฐ ์•„์ด๋””์–ด 

 

ํŒŒ์ด์ฌ ์ฝ”๋“œ 

n = int(input())
arr = list(map(int, input().split()))
d = [0]*100

# ๋ณดํ…€์—„ ๋ฐฉ์‹
d[0] = arr[0]
d[1] = max(arr[0], arr[1])
for i in range(2, n):
    d[i] = max(d[i-1], d[i-2]+arr[i])
print(d[n-1]) # 8

 

728x90