Skip to content

Latest commit

ย 

History

History
135 lines (97 loc) ยท 4.89 KB

Dynamic_Programming.md

File metadata and controls

135 lines (97 loc) ยท 4.89 KB

๋™์ ๊ณ„ํš๋ฒ• (Dynamic Programming)

ํ•˜๋‚˜์˜ ํฐ ๋ฌธ์ œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„์–ด์„œ
๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜์—ฌ ๋‹ค์‹œ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

๋™์ ๊ณ„ํš๋ฒ•, ์ฆ‰ DP๋Š” ์‹คํ–‰ ์‹œ๊ฐ„์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์ˆ˜ํ•™์  ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž…๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ„ํ•  ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ๋™์  ๊ณ„ํš๋ฒ•์—์„œ๋Š” ์ชผ๊ฐœ์ง„ ์ž‘์€ ๋ฌธ์ œ๊ฐ€ ์ค‘๋ณต๋˜๊ณ ,
๋ถ„ํ•  ์ •๋ณต์€ ์ ˆ๋Œ€๋กœ ์ค‘๋ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

image

์กฐ๊ฑด

๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ๋™์  ๊ณ„ํš๋ฒ•์œผ๋กœ ๋ฌธ์ œํ’€์ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  1. Overlapping Subproblem : ๊ฒน์น˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ
  2. Optimal Substructure : ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ

1๏ธโƒฃ Overlapping Subproblems

DP๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ๋‚˜๋ˆ„๊ณ  ๊ทธ ๋ฌธ์ œ์˜ ๊ฒฐ๊ณผ ๊ฐ’์„ ์žฌํ™œ์šฉํ•ด์„œ ์ „์ฒด ๋‹ต์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋™์ผํ•œ ์ž‘์€ ๋ฌธ์ œ๋“ค์ด ๋ฐ˜๋ณตํ•˜์—ฌ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, DP๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜์—ฌ ์žฌ ๊ณ„์‚ฐํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ,
ํ•ด๋‹น ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์žฌ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ˆ ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃ Optimal Substructure

๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ตœ์  ๊ฒฐ๊ณผ ๊ฐ’์„ ์‚ฌ์šฉํ•ด ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์  ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํŠน์ • ๋ฌธ์ œ์˜ ์ •๋‹ต์€ ๋ฌธ์ œ์˜ ํฌ๊ธฐ์— ์ƒ๊ด€์—†์ด ํ•ญ์ƒ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฐฉ๋ฒ•

DP๋Š” ํŠน์ •ํ•œ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•๋ก ์ด๋ฏ€๋กœ ๋‹ค์–‘ํ•œ ๋ฌธ์ œํ•ด๊ฒฐ์— ์“ฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ DP๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ธ์ง€๋ฅผ ์•Œ์•„๋‚ด๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ณผ์ •์ด ๋‚œ์ด๋„๊ฐ€ ์‰ฌ์šด ๊ฒƒ๋ถ€ํ„ฐ ์–ด๋ ค์šด ๊ฒƒ๊นŒ์ง€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค.

  1. DP๋กœ ํ’€ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ธ์ง€ ํ™•์ธ
  2. ๋ฌธ์ œ์˜ ๋ณ€์ˆ˜ ํŒŒ์•…
  3. ๋ณ€์ˆ˜ ๊ฐ„ ๊ด€๊ณ„์‹ ๋งŒ๋“ค๊ธฐ(์ ํ™”์‹)
  4. ๋ฉ”๋ชจ(memoization or tabulation)
  5. ๊ธฐ์ € ์ƒํƒœ ํŒŒ์•…
  6. ๊ตฌํ˜„

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

ํ•œ ๋ฒˆ ๊ณ„์‚ฐํ•œ ๋ฌธ์ œ๋Š” ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋„๋ก ์ €์žฅํ•ด๋‘๊ณ  ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹

์˜ˆ์‹œ) fibonacciํ•จ์ˆ˜

fibonacci(5) = fibonacci(4) + fibonacci(3)
fibonacci(4) = fibonacci(3) + fibonacci(2)
fibonacci(3) = fibonacci(2) + fibonacci(1)

์ด์ฒ˜๋Ÿผ ๊ฐ™์€ ์—ฐ์‚ฐ์ด ๊ณ„์† ๋ฐ˜๋ณต์ ์œผ๋กœ ์ด์šฉ๋  ๋•Œ, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ™œ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋‘๋ฉด ํšจ์œจ์ 

ํ”ผ๋ณด๋‚˜์น˜ ๊ตฌํ˜„์— ์žฌ๊ท€๋ฅผ ํ™œ์šฉํ–ˆ๋‹ค๋ฉด ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(2^n)์ด์ง€๋งŒ, ๋™์  ๊ณ„ํš๋ฒ•์„ ํ™œ์šฉํ•˜๋ฉด O(N)์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„ ๋ฐฉ์‹

๋™์  ๊ณ„ํš๋ฒ•์˜ ๊ตฌํ˜„ ๋ฐฉ์‹์—๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • Top-down : ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ์ชผ๊ฐœ์–ด ํ‘ธ๋Š” ๋ฐฉ๋ฒ• (์žฌ๊ท€ํ•จ์ˆ˜)
  • Bottom-up : ์ž‘์€ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ• (๋ฐ˜๋ณต๋ฌธ)

Bottom-up ์€ ํ•ด๊ฒฐ์ด ์šฉ์ดํ•˜์ง€๋งŒ, ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง
Top-down์€ ๊ฐ€๋…์„ฑ์ด ์ข‹์ง€๋งŒ, ์ฝ”๋“œ ์ž‘์„ฑ์ด ์–ด๋ ค์›€

๐Ÿ“Œ์˜ˆ์ œ (Baekjoon)

1๋กœ ๋งŒ๋“ค๊ธฐ

๋ฌธ์ œ

image

ํ’€์ด

Overlapping Subproblem์™€, Optimal Substructure 2๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋ฏ€๋กœ,
DP๋ฅผ ์ด์šฉํ•˜์—ฌ ํ’€์ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ผ๋‹จ, 2์™€ 3์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋Š” ๋ฌด์กฐ๊ฑด 1์„ ๋นผ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—

dp[i] = dp[i - 1] + 1์„ ํ†ตํ•ด ํšŸ์ˆ˜๋ฅผ +1 ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ ๋‚˜์„œ, dp[i]๊ฐ€ 2 ์™€ 3์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ์—๋Š”

1์„ ๋นผ๋Š” ๊ฒƒ ๋ณด๋‹ค ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š”๊ฒŒ ํ›จ์”ฌ ์ด๋“์ด๊ธฐ ๋•Œ๋ฌธ์—

min(dp[i], dp[i//2]+1)์„ ํ†ตํ•ด ์ตœ์†Œ๊ฐ’์„ ์„ ํƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ (Python) - Bottom-up(๋ฐ˜๋ณต๋ฌธ)

import sys
input = sys.stdin.readline

n = int(input())

dp = {
  0 : 0,
  1 : 0,
}

for i in range(2, n + 1):
  dp[i] = dp[i - 1] + 1

  if i % 2 == 0:
    dp[i] = min(dp[i], dp[i // 2] + 1)

  if i % 3 == 0:
    dp[i] = min(dp[i], dp[i // 3] + 1)

print(dp[n])

์ฝ”๋“œ (Python) - Up-down(์žฌ๊ท€ํ•จ์ˆ˜)

import sys
input = sys.stdin.readline

num = int(input())

dp = {
  0 : 0,
  1 : 0,
}

def rec(n):
    if n in dp.keys():
        return dp[n]
    if n % 3 == 0 and n % 2 == 0:
        dp[n] = min(rec(n//3) + 1, rec(n//2) + 1)
    elif n % 3 == 0:
        dp[n] = min(rec(n//3) + 1, rec(n-1) + 1)
    elif n % 2 == 0:
        dp[n] = min(rec(n//2) + 1, rec(n-1) + 1)
    else:
        dp[n] = rec(n-1) + 1
    return dp[n]

print(rec(num))

Reference

https://velog.io/@polynomeer/%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming