์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿงฉ ๋™์ ๊ณ„ํš๋ฒ• ์™„์ „์ •๋ณต

๐Ÿงฉ ๋™์ ๊ณ„ํš๋ฒ• ์™„์ „์ •๋ณต

Dynamic Programming ยท ์–ด๋ ค์šด ์ˆ˜ํ•™์˜ ๊ฝƒ ยท ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹ฌ์žฅ

"๊ฐ™์€ ๊ณ„์‚ฐ์„ ๋‘ ๋ฒˆ ํ•˜์ง€ ์•Š๋Š” ์ฒœ์žฌ์ ์ธ ๋ฐœ์ƒ โ€” DP์˜ ์„ธ๊ณ„๋กœ ๋– ๋‚˜๋ณด์ž! ๐Ÿš€"

์•ผ, ์†”์งํžˆ ๋งํ• ๊ฒŒ. ๋™์ ๊ณ„ํš๋ฒ•(Dynamic Programming, DP)์€ ์ฒ˜์Œ ๋“ค์—ˆ์„ ๋•Œ ์ด๋ฆ„๋ถ€ํ„ฐ ๋ญ”๊ฐ€ ๋ฌด์„ญ์ง€ ์•Š์•„? ๐Ÿ˜…
"๋™์ "์ด๋ผ๋Š” ๋‹จ์–ด๋„ ๊ทธ๋ ‡๊ณ , "๊ณ„ํš๋ฒ•"์ด๋ผ๋Š” ๋‹จ์–ด๋„ ๊ทธ๋ ‡๊ณ ... ๋ญ”๊ฐ€ ์—„์ฒญ ๋ณต์žกํ•œ ์ˆ˜ํ•™ ์ด๋ก  ๊ฐ™์€ ๋А๋‚Œ.
๊ทผ๋ฐ ๋ง‰์ƒ ํŒŒ๊ณ ๋“ค๋ฉด ์ง„์งœ ์šฐ์•„ํ•˜๊ณ  ์•„๋ฆ„๋‹ค์šด ์•„์ด๋””์–ด์•ผ. ์˜ค๋Š˜ ๋‚˜๋ž‘ ๊ฐ™์ด ์ด ์„ธ๊ณ„๋ฅผ ์™„์ „ํžˆ ๋œฏ์–ด๋ณด์ž! ๐Ÿ’ช

์ด ๊ธ€์„ ๋‹ค ์ฝ๊ณ  ๋‚˜๋ฉด DP๊ฐ€ ์™œ ์ˆ˜ํ•™๊ณผ ์ปดํ“จํ„ฐ๊ณผํ•™์—์„œ ๊ทธํ† ๋ก ์ค‘์š”ํ•œ์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€ ํ™•์‹คํžˆ ์•Œ๊ฒŒ ๋  ๊ฑฐ์•ผ.


๐Ÿ“– 1. ๋™์ ๊ณ„ํš๋ฒ•์ด๋ž€ ๋ญ์•ผ?

๋™์ ๊ณ„ํš๋ฒ•์€ 1950๋…„๋Œ€ ๋ฏธ๊ตญ์˜ ์ˆ˜ํ•™์ž ๋ฆฌ์ฒ˜๋“œ ๋ฒจ๋งŒ(Richard Bellman)์ด ๊ฐœ๋ฐœํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ด์•ผ.
์ด๋ฆ„์ด ์ข€ ์ด์ƒํ•˜์ง€? "Dynamic Programming"์ธ๋ฐ ์‚ฌ์‹ค ์—ฌ๊ธฐ์„œ "Dynamic"์€ ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์“ฐ๋Š” "๋™์ ์ธ"์˜ ์˜๋ฏธ๊ฐ€ ์•„๋‹ˆ์•ผ.
๋ฒจ๋งŒ ๋ณธ์ธ์ด ๋‚˜์ค‘์— ๋ฐํžˆ๊ธธ, ๋‹น์‹œ ์—ฐ๊ตฌ๋น„๋ฅผ ์ง€์›ํ•˜๋˜ ๊ตญ๋ฐฉ๋ถ€๊ฐ€ "์ˆ˜ํ•™ ์—ฐ๊ตฌ"๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์‹ซ์–ดํ•ด์„œ ๊ทธ๋ƒฅ ๋ฉ‹์žˆ์–ด ๋ณด์ด๋Š” ์ด๋ฆ„์„ ๊ณจ๋ž๋‹ค๊ณ  ํ•ด ๐Ÿ˜‚
๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ด๋ฆ„์— ๋„ˆ๋ฌด ๊ฒ๋จน์ง€ ๋งˆ!

๐Ÿ’ก ํ•ต์‹ฌ ์•„์ด๋””์–ด ํ•œ ์ค„ ์š”์•ฝ: "ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๋กœ ์ชผ๊ฐœ๊ณ , ์ด๋ฏธ ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋Š” ์ €์žฅํ•ด์„œ ์žฌ์‚ฌ์šฉํ•œ๋‹ค!"

์ด๊ฒŒ ์ „๋ถ€์•ผ. ์ง„์งœ๋กœ. ๋ฌผ๋ก  ์ด๊ฑธ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฑด ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ๊ณผ ํ†ต์ฐฐ์ด ํ•„์š”ํ•˜์ง€๋งŒ,
ํ•ต์‹ฌ ์ฒ ํ•™์€ ๋”ฑ ์ด ํ•œ ์ค„์ด์•ผ. ์ค‘๋ณต ๊ณ„์‚ฐ์„ ์—†์• ์„œ ํšจ์œจ์„ ๊ทน์ ์œผ๋กœ ๋†’์ด๋Š” ๊ฒƒ.

๐Ÿ” DP๊ฐ€ ์ ์šฉ๋˜๋Š” ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด
1
์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ (Optimal Substructure)
ํฐ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๊ฐ€ ์ž‘์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์˜ ์ตœ์ ํ•ด๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ด.
์˜ˆ๋ฅผ ๋“ค์–ด ์„œ์šธ์—์„œ ๋ถ€์‚ฐ๊นŒ์ง€ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š”๋‹ค๋ฉด, ๊ทธ ๊ฒฝ๋กœ ์œ„์˜ ์–ด๋–ค ์ค‘๊ฐ„ ๋„์‹œ๋ฅผ ๊ฑฐ์ณ๋„ ๊ทธ ๊ตฌ๊ฐ„์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฑฐ์•ผ.
2
์ค‘๋ณต ๋ถ€๋ถ„ ๋ฌธ์ œ (Overlapping Subproblems)
๊ฐ™์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณตํ•ด์„œ ๋“ฑ์žฅํ•ด์•ผ ํ•ด.
๋งŒ์•ฝ ๋ชจ๋“  ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋”ฑ ํ•œ ๋ฒˆ์”ฉ๋งŒ ๋‚˜์˜จ๋‹ค๋ฉด ๊ตณ์ด DP๋ฅผ ์“ธ ํ•„์š”๊ฐ€ ์—†์–ด. ๊ทธ๋ƒฅ ๋ถ„ํ• ์ •๋ณต์œผ๋กœ ํ•ด๊ฒฐํ•˜๋ฉด ๋˜๊ฑฐ๋“ .

์ด ๋‘ ์กฐ๊ฑด์ด ๋ชจ๋‘ ๋งŒ์กฑ๋  ๋•Œ DP๋Š” ๋งˆ๋ฒ• ๊ฐ™์€ ํšจ์œจ์„ ๋ฐœํœ˜ํ•ด. ์ง€๊ธˆ๋ถ€ํ„ฐ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ณด์ž!


๐Ÿ‡ 2. ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด๋กœ DP ๋ง›๋ณด๊ธฐ

DP๋ฅผ ์„ค๋ช…ํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๋Š” ์˜ˆ์‹œ๊ฐ€ ๋ฐ”๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์ด์•ผ.
ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์€ ์ด๋ ‡๊ฒŒ ์ •์˜๋ผ:

F(0) = 0, F(1) = 1
F(n) = F(n-1) + F(n-2) (n โ‰ฅ 2)

์ฆ‰, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ... ์ด๋ ‡๊ฒŒ ์ด์–ด์ง€๋Š” ์ˆ˜์—ด์ด์•ผ.
์ด๊ฑธ ์ˆœ์ง„ํ•˜๊ฒŒ ์žฌ๊ท€๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

์ฝ”๋“œ๋Š” ๊น”๋”ํ•œ๋ฐ... ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด. F(5)๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์„ ๊ทธ๋ฆผ์œผ๋กœ ๋ณด๋ฉด:

ํ”ผ๋ณด๋‚˜์น˜ ์žฌ๊ท€ ํ˜ธ์ถœ ํŠธ๋ฆฌ โ€” F(5) ๊ณ„์‚ฐ F(5) F(4) F(3)โ‘  F(3)โ‘ก F(2)โ‘  F(2)โ‘ก F(1) F(2)โ‘ข F(1) F(1) F(0) F(1) F(0) F(1) F(0) โš ๏ธ ์ค‘๋ณต ๊ณ„์‚ฐ ๋ฐœ์ƒ! F(3): 2๋ฒˆ, F(2): 3๋ฒˆ F(1): 5๋ฒˆ, F(0): 3๋ฒˆ ๊ณ„์‚ฐ๋จ

๋ณด์ด์ง€? F(3)์ด 2๋ฒˆ, F(2)๊ฐ€ 3๋ฒˆ, F(1)์ด ๋ฌด๋ ค 5๋ฒˆ ๊ณ„์‚ฐ๋ผ!
n์ด ์ปค์งˆ์ˆ˜๋ก ์ด ์ค‘๋ณต์€ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ๋Š˜์–ด๋‚˜. F(50)์„ ์ด๋ ‡๊ฒŒ ๊ณ„์‚ฐํ•˜๋ฉด ์ˆ˜์‹ญ์–ต ๋ฒˆ์˜ ์—ฐ์‚ฐ์ด ํ•„์š”ํ•ด ๐Ÿ˜ฑ
์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(2โฟ)์ด๊ฑฐ๋“ . ์™„์ „ ํญ๋ฐœ์ ์œผ๋กœ ๋Š˜์–ด๋‚˜๋Š” ๊ฑฐ์•ผ.

โœจ DP๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ โ€” ๋ฉ”๋ชจ์ด์ œ์ด์…˜

DP์˜ ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ธ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization)์„ ์จ๋ณด์ž.
"์ด๋ฏธ ๊ณ„์‚ฐํ•œ ๊ฐ’์€ ์ €์žฅํ•ด๋‘๊ณ , ๋‹ค์‹œ ํ•„์š”ํ•˜๋ฉด ๊บผ๋‚ด ์“ด๋‹ค"๋Š” ์•„์ด๋””์–ด์•ผ.

memo = {}

def fib_dp(n):
    if n <= 1:
        return n
    if n in memo:          # ์ด๋ฏธ ๊ณ„์‚ฐํ–ˆ์œผ๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜!
        return memo[n]
    memo[n] = fib_dp(n-1) + fib_dp(n-2)
    return memo[n]

์ด์ œ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(n)์œผ๋กœ ์ค„์–ด๋“ค์–ด! ๊ฐ ๊ฐ’์„ ๋”ฑ ํ•œ ๋ฒˆ์”ฉ๋งŒ ๊ณ„์‚ฐํ•˜๋‹ˆ๊นŒ.
F(50)๋„ ์ˆœ์‹๊ฐ„์— ๊ณ„์‚ฐ๋ผ. ์ด๊ฒŒ DP์˜ ๋งˆ๋ฒ•์ด์•ผ โœจ

๐Ÿ”„ ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ• โ€” ๋ฐ”ํ…€์—…(Bottom-Up)

๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด "์œ„์—์„œ ์•„๋ž˜๋กœ(Top-Down)" ๋ฐฉ์‹์ด๋ผ๋ฉด,
๋ฐ”ํ…€์—…(Bottom-Up)์€ "์•„๋ž˜์—์„œ ์œ„๋กœ" ์˜ฌ๋ผ๊ฐ€๋Š” ๋ฐฉ์‹์ด์•ผ.
์ž‘์€ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ฐจ๋ก€์ฐจ๋ก€ ํ’€์–ด๋‚˜๊ฐ€๋Š” ๊ฑฐ์ง€.

def fib_bottom_up(n):
    if n <= 1:
        return n
    dp = [0] * (n + 1)
    dp[0] = 0
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i-1] + dp[i-2]   # ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’ ํ™œ์šฉ!
    return dp[n]

์ด ๋ฐฉ์‹์€ ์žฌ๊ท€ ํ˜ธ์ถœ์ด ์—†์–ด์„œ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๊ฑฑ์ •๋„ ์—†๊ณ , ๋ฉ”๋ชจ๋ฆฌ๋„ ๋” ํšจ์œจ์ ์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ์–ด.
์‹ฌ์ง€์–ด ๋ณ€์ˆ˜ ๋‘ ๊ฐœ๋งŒ ์จ์„œ O(1) ๊ณต๊ฐ„์œผ๋กœ๋„ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ด!

๋ฐฉ๋ฒ•์‹œ๊ฐ„ ๋ณต์žก๋„๊ณต๊ฐ„ ๋ณต์žก๋„ํŠน์ง•
์ˆœ์ˆ˜ ์žฌ๊ท€O(2โฟ)O(n)์ง๊ด€์ ์ด์ง€๋งŒ ๋งค์šฐ ๋А๋ฆผ
๋ฉ”๋ชจ์ด์ œ์ด์…˜(Top-Down)O(n)O(n)์žฌ๊ท€ + ์บ์‹ฑ
๋ฐ”ํ…€์—…(Bottom-Up)O(n)O(n) ~ O(1)๋ฐ˜๋ณต๋ฌธ, ์•ˆ์ •์ 

๐ŸŽ’ 3. ๋ฐฐ๋‚ญ ๋ฌธ์ œ (Knapsack Problem)

DP์˜ ํด๋ž˜์‹ ์ค‘์˜ ํด๋ž˜์‹! ๋ฐฐ๋‚ญ ๋ฌธ์ œ์•ผ. ๐ŸŽ’
์ด ๋ฌธ์ œ๋Š” ์ˆ˜ํ•™, ๊ฒฝ์ œํ•™, ์ปดํ“จํ„ฐ๊ณผํ•™ ์ „๋ฐ˜์—์„œ ์—„์ฒญ๋‚˜๊ฒŒ ์ค‘์š”ํ•˜๊ฒŒ ๋‹ค๋ค„์ ธ.
๋ฌธ์ œ ์ƒํ™ฉ์€ ์ด๋ž˜:

๋ฌด๊ฒŒ ํ•œ๋„๊ฐ€ W์ธ ๋ฐฐ๋‚ญ์ด ์žˆ์–ด. n๊ฐœ์˜ ๋ฌผ๊ฑด์ด ์žˆ๋Š”๋ฐ, ๊ฐ ๋ฌผ๊ฑด์€ ๋ฌด๊ฒŒ(w)์™€ ๊ฐ€์น˜(v)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด.
๋ฐฐ๋‚ญ์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๋ฌผ๊ฑด๋“ค์˜ ๊ฐ€์น˜ ํ•ฉ์„ ์ตœ๋Œ€๋กœ ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?
(๋‹จ, ๊ฐ ๋ฌผ๊ฑด์€ ํ•œ ๋ฒˆ์”ฉ๋งŒ ๋„ฃ์„ ์ˆ˜ ์žˆ์–ด โ€” 0/1 ๋ฐฐ๋‚ญ ๋ฌธ์ œ)
๐ŸŽ’ ๋ฐฐ๋‚ญ ๋ฌธ์ œ ์‹œ๊ฐํ™” ๋ฐฐ๋‚ญ ์ตœ๋Œ€ ๋ฌด๊ฒŒ: 7kg ๋ฌผ๊ฑด A ๋ฌด๊ฒŒ: 2kg ๊ฐ€์น˜: 6๋งŒ์› ๋ฌผ๊ฑด B ๋ฌด๊ฒŒ: 3kg ๊ฐ€์น˜: 10๋งŒ์› ๋ฌผ๊ฑด C ๋ฌด๊ฒŒ: 4kg ๊ฐ€์น˜: 12๋งŒ์› ๋ฌผ๊ฑด D ๋ฌด๊ฒŒ: 5kg ๊ฐ€์น˜: 15๋งŒ์› DP ์ตœ์ ํ•ด ๋ฌผ๊ฑด A (2kg, 6๋งŒ์›) + ๋ฌผ๊ฑด B (3kg, 10๋งŒ์›) ์ด ๋ฌด๊ฒŒ: 5kg โ‰ค 7kg โœ“ ์ด ๊ฐ€์น˜: 16๋งŒ์› ๐Ÿ† (A+C=18๋งŒ์›์ด์ง€๋งŒ ๋ฌด๊ฒŒ 6kg) โ†’ A B DP ์ ํ™”์‹: dp[i][w] = max(dp[i-1][w], dp[i-1][w-weight[i]] + value[i]) i๋ฒˆ์งธ ๋ฌผ๊ฑด์„ ๋„ฃ์„์ง€(์˜ค๋ฅธ์ชฝ) ๋ง์ง€(์™ผ์ชฝ) ์„ ํƒํ•˜๋Š” ์ตœ์  ๊ฒฐ์ •!
๐Ÿ“ ์ ํ™”์‹ ์ดํ•ดํ•˜๊ธฐ

๋ฐฐ๋‚ญ ๋ฌธ์ œ์˜ DP ์ ํ™”์‹์€ ์ด๋ž˜:

dp[i][w] = i๋ฒˆ์งธ ๋ฌผ๊ฑด๊นŒ์ง€ ๊ณ ๋ คํ–ˆ์„ ๋•Œ, ๋ฌด๊ฒŒ ํ•œ๋„๊ฐ€ w์ผ ๋•Œ์˜ ์ตœ๋Œ€ ๊ฐ€์น˜

dp[i][w] = max(dp[i-1][w], dp[i-1][w - weight[i]] + value[i])

โ†’ i๋ฒˆ์งธ ๋ฌผ๊ฑด์„ ์•ˆ ๋„ฃ๋Š” ๊ฒฝ์šฐ: dp[i-1][w]
โ†’ i๋ฒˆ์งธ ๋ฌผ๊ฑด์„ ๋„ฃ๋Š” ๊ฒฝ์šฐ: dp[i-1][w - weight[i]] + value[i]

์ด ์ ํ™”์‹์ด ํ•ต์‹ฌ์ด์•ผ. "๋„ฃ์„๊นŒ ๋ง๊นŒ"๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฑฐ์•ผ.
์ด๊ฑธ ํ‘œ๋กœ ์ฑ„์›Œ๋‚˜๊ฐ€๋ฉด O(n ร— W)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ์ตœ์ ํ•ด๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์–ด!
์™„์ „ ํƒ์ƒ‰์ด๋ผ๋ฉด 2โฟ๊ฐ€์ง€๋ฅผ ๋‹ค ๋ด์•ผ ํ•˜๋Š”๋ฐ, DP๋ฅผ ์“ฐ๋ฉด ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐ๋˜์ง€.

def knapsack(weights, values, W):
    n = len(weights)
    dp = [[0] * (W + 1) for _ in range(n + 1)]
    
    for i in range(1, n + 1):
        for w in range(W + 1):
            # ๋ฌผ๊ฑด์„ ์•ˆ ๋„ฃ๋Š” ๊ฒฝ์šฐ
            dp[i][w] = dp[i-1][w]
            # ๋ฌผ๊ฑด์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ณ , ๋„ฃ๋Š” ๊ฒŒ ๋” ์ด๋“์ด๋ฉด
            if weights[i-1] <= w:
                dp[i][w] = max(dp[i][w], 
                               dp[i-1][w - weights[i-1]] + values[i-1])
    
    return dp[n][W]

๐Ÿ›ค๏ธ 4. ์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด (LCS)

LCS(Longest Common Subsequence)๋Š” ๋‘ ๋ฌธ์ž์—ด์—์„œ ๊ณตํ†ต์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ์ฐพ๋Š” ๋ฌธ์ œ์•ผ.
์ด๊ฒŒ ์™œ ์ค‘์š”ํ•˜๋ƒ๊ณ ? DNA ์„œ์—ด ๋ถ„์„, ํŒŒ์ผ ๋น„๊ต(diff), ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ๋“ฑ์— ์‹ค์ œ๋กœ ์“ฐ์—ฌ!

์˜ˆ์‹œ: "ABCBDAB"์™€ "BDCAB"์˜ LCS๋Š”?
โ†’ "BCAB" ๋˜๋Š” "BDAB" (๊ธธ์ด 4)
๐Ÿ“Š LCS ์ ํ™”์‹
X[i] == Y[j]์ด๋ฉด: dp[i][j] = dp[i-1][j-1] + 1
X[i] != Y[j]์ด๋ฉด: dp[i][j] = max(dp[i-1][j], dp[i][j-1])

์ด ์ ํ™”์‹๋„ ์ง๊ด€์ ์ด์•ผ:
๋‘ ๋ฌธ์ž๊ฐ€ ๊ฐ™์œผ๋ฉด ์ด์ „ ๊ฒฐ๊ณผ์— 1์„ ๋”ํ•˜๊ณ ,
๋‹ค๋ฅด๋ฉด ํ•œ ์ชฝ์„ ์ œ์™ธํ–ˆ์„ ๋•Œ์˜ ์ตœ๋Œ“๊ฐ’์„ ์ทจํ•˜๋Š” ๊ฑฐ์•ผ.

def lcs(X, Y):
    m, n = len(X), len(Y)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if X[i-1] == Y[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    
    return dp[m][n]

print(lcs("ABCBDAB", "BDCAB"))  # ์ถœ๋ ฅ: 4

์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(m ร— n)์ด์•ผ. ๋‘ ๋ฌธ์ž์—ด ๊ธธ์ด์˜ ๊ณฑ์— ๋น„๋ก€ํ•˜๋Š” ๊ฑฐ์ง€.
์™„์ „ ํƒ์ƒ‰์œผ๋กœ ํ•˜๋ฉด ์ง€์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š”๋ฐ, DP ๋•๋ถ„์— ๋‹คํ•ญ ์‹œ๊ฐ„์œผ๋กœ ํ•ด๊ฒฐ๋ผ! ๐ŸŽ‰


๐Ÿ—บ๏ธ 5. ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ์™€ DP

DP๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ๋„ ํ•ต์‹ฌ์ ์œผ๋กœ ์“ฐ์—ฌ.
๋Œ€ํ‘œ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋ฒจ๋งŒ-ํฌ๋“œ(Bellman-Ford)์™€ ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ(Floyd-Warshall)์ด์•ผ.

๐Ÿ”ต ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ชจ๋“  ์Œ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํ•œ ๋ฒˆ์— ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์•ผ.
ํ•ต์‹ฌ ์•„์ด๋””์–ด: "k๋ฒˆ ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ์„œ ๊ฐ€๋ฉด ๋” ์งง์•„์ง€์ง€ ์•Š์„๊นŒ?"

์ ํ™”์‹: dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) i์—์„œ j๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฑฐ๋ฆฌ = min(์ง์ ‘ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ, k๋ฅผ ๊ฒฝ์œ ํ•ด์„œ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ)
def floyd_warshall(graph, n):
    dist = [[float('inf')] * n for _ in range(n)]
    
    # ์ดˆ๊ธฐํ™”
    for i in range(n):
        dist[i][i] = 0
    for u, v, w in graph:
        dist[u][v] = w
    
    # ๋ชจ๋“  ์ค‘๊ฐ„ ๋…ธ๋“œ k๋ฅผ ์‹œ๋„
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]
    
    return dist

์‹œ๊ฐ„ ๋ณต์žก๋„ O(nยณ)์ด์ง€๋งŒ, ๋ชจ๋“  ์Œ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํ•œ ๋ฒˆ์— ๊ตฌํ•  ์ˆ˜ ์žˆ์–ด.
์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜๋„ DP์˜ ํ•ต์‹ฌ ์›๋ฆฌ์ธ "์ด๋ฏธ ๊ณ„์‚ฐํ•œ ์ตœ์ ํ•ด๋ฅผ ์žฌํ™œ์šฉ"ํ•˜๋Š” ๊ฑฐ์•ผ.

ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ: ์ค‘๊ฐ„ ๋…ธ๋“œ k๋ฅผ ํ†ตํ•œ ๊ฒฝ๋กœ ๊ฐฑ์‹  A B C (์ค‘๊ฐ„ ๋…ธ๋“œ k) D 8 3 2 5 ์ง์ ‘: 12 Aโ†’Cโ†’D = 3+2 = 5 โœ“ (๋” ์งง์Œ!) dist[A][D] = min(12, 5) = 5 ๋กœ ๊ฐฑ์‹ ! k = C ์‹œ๋„ Aโ†’C: 3 Cโ†’D: 2 โ†’ ํ•ฉ๊ณ„ 5!

๐Ÿงฎ 6. ๋™์ „ ๊ตํ™˜ ๋ฌธ์ œ (Coin Change)

์ด๊ฒƒ๋„ DP์˜ ๋Œ€ํ‘œ ๋ฌธ์ œ์•ผ! ์‹ค์ƒํ™œ์—์„œ๋„ ๋ฐ”๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ๋ฌธ์ œ๊ฑฐ๋“ .
๋™์ „์˜ ์ข…๋ฅ˜๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ํŠน์ • ๊ธˆ์•ก์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ตœ์†Œ ๋™์ „ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๊ฑฐ์•ผ.

๋™์ „ ์ข…๋ฅ˜: [1์›, 5์›, 10์›, 25์›]
๋ชฉํ‘œ ๊ธˆ์•ก: 36์›
์ตœ์†Œ ๋™์ „ ๊ฐœ์ˆ˜๋Š”? โ†’ 25 + 10 + 1 = 3๊ฐœ!
์ ํ™”์‹: dp[i] = min(dp[i], dp[i - coin] + 1) dp[i] = ๊ธˆ์•ก i๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ตœ์†Œ ๋™์ „ ๊ฐœ์ˆ˜
๊ฐ ๋™์ „ coin์— ๋Œ€ํ•ด, dp[i - coin] + 1๊ณผ ๋น„๊ตํ•ด์„œ ์ตœ์†Ÿ๊ฐ’ ์„ ํƒ
def coin_change(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0  # 0์›์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๋™์ „: 0๊ฐœ
    
    for i in range(1, amount + 1):
        for coin in coins:
            if coin <= i:
                dp[i] = min(dp[i], dp[i - coin] + 1)
    
    return dp[amount] if dp[amount] != float('inf') else -1

print(coin_change([1, 5, 10, 25], 36))  # ์ถœ๋ ฅ: 3

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ! ํƒ์š• ์•Œ๊ณ ๋ฆฌ์ฆ˜(Greedy)์œผ๋กœ๋Š” ํ•ญ์ƒ ์ตœ์ ํ•ด๋ฅผ ๊ตฌํ•  ์ˆ˜ ์—†์–ด.
์˜ˆ๋ฅผ ๋“ค์–ด ๋™์ „์ด [1, 3, 4]์ด๊ณ  ๋ชฉํ‘œ๊ฐ€ 6์ด๋ผ๋ฉด:
ํƒ์š•: 4 + 1 + 1 = 3๊ฐœ
DP: 3 + 3 = 2๊ฐœ โ† ๋” ์ ์–ด!
์ด๋Ÿฐ ๊ฒฝ์šฐ์— DP๊ฐ€ ์ง„๊ฐ€๋ฅผ ๋ฐœํœ˜ํ•˜๋Š” ๊ฑฐ์•ผ ๐Ÿ’ช


๐Ÿ“ˆ 7. ์ตœ์žฅ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด (LIS)

LIS(Longest Increasing Subsequence)๋Š” ์ˆ˜์—ด์—์„œ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ์ฐพ๋Š” ๋ฌธ์ œ์•ผ.
์ฃผ์‹ ๋ถ„์„, ํŒจํ„ด ์ธ์‹ ๋“ฑ์— ํ™œ์šฉ๋ผ!

์ˆ˜์—ด: [10, 9, 2, 5, 3, 7, 101, 18]
LIS: [2, 3, 7, 101] ๋˜๋Š” [2, 5, 7, 101] โ†’ ๊ธธ์ด 4
์ ํ™”์‹: dp[i] = max(dp[j] + 1) for all j < i where arr[j] < arr[i] dp[i] = arr[i]๋กœ ๋๋‚˜๋Š” LIS์˜ ๊ธธ์ด
def lis(arr):
    n = len(arr)
    dp = [1] * n  # ๊ฐ ์›์†Œ ์ž์ฒด๋งŒ์œผ๋กœ ๊ธธ์ด 1
    
    for i in range(1, n):
        for j in range(i):
            if arr[j] < arr[i]:  # ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ
                dp[i] = max(dp[i], dp[j] + 1)
    
    return max(dp)

print(lis([10, 9, 2, 5, 3, 7, 101, 18]))  # ์ถœ๋ ฅ: 4

์ด O(nยฒ) ํ’€์ด๋ฅผ ์ด์ง„ ํƒ์ƒ‰์„ ํ™œ์šฉํ•˜๋ฉด O(n log n)์œผ๋กœ ๋” ๋น ๋ฅด๊ฒŒ ํ’€ ์ˆ˜๋„ ์žˆ์–ด!
DP๋Š” ์ด๋ ‡๊ฒŒ ๋‹ค๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๊ฒฐํ•ฉํ•ด์„œ ๋” ๊ฐ•๋ ฅํ•ด์ง€๊ธฐ๋„ ํ•ด.


๐Ÿ—๏ธ 8. DP ๋ฌธ์ œ ํ’€์ด ์ „๋žต โ€” ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ• ๊นŒ?

DP ๋ฌธ์ œ๋ฅผ ์ฒ˜์Œ ๋ณด๋ฉด ๋ง‰๋ง‰ํ•˜์ง€? ๐Ÿ˜… ๊ทผ๋ฐ ์ฒด๊ณ„์ ์ธ ์ ‘๊ทผ๋ฒ•์ด ์žˆ์–ด!

1
์ƒํƒœ(State) ์ •์˜ํ•˜๊ธฐ
dp[i], dp[i][j] ๋“ฑ โ€” ๋ฌด์—‡์„ ์ €์žฅํ• ์ง€ ๋ช…ํ™•ํžˆ ์ •์˜ํ•ด.
"dp[i]๋Š” ~์ผ ๋•Œ์˜ ์ตœ์ ๊ฐ’์ด๋‹ค"๋ผ๊ณ  ๋ง๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ด.
2
์ ํ™”์‹(Recurrence Relation) ์„ธ์šฐ๊ธฐ
ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ์–ด๋–ป๊ฒŒ ์ชผ๊ฐค ์ˆ˜ ์žˆ๋Š”์ง€ ๊ด€๊ณ„์‹์„ ์ฐพ์•„.
์ด๊ฒŒ DP์˜ ํ•ต์‹ฌ์ด์ž ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด์•ผ.
3
์ดˆ๊ธฐ๊ฐ’(Base Case) ์„ค์ •ํ•˜๊ธฐ
๊ฐ€์žฅ ์ž‘์€ ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ๋‹ต์„ ์ง์ ‘ ์„ค์ •ํ•ด.
์˜ˆ: dp[0] = 0, dp[1] = 1 ๋“ฑ
4
๊ณ„์‚ฐ ์ˆœ์„œ ๊ฒฐ์ •ํ•˜๊ธฐ
๋ฐ”ํ…€์—…์ด๋ผ๋ฉด ์–ด๋–ค ์ˆœ์„œ๋กœ ์ฑ„์›Œ๋‚˜๊ฐˆ์ง€ ๊ฒฐ์ •ํ•ด.
์ž‘์€ ๋ฌธ์ œ๊ฐ€ ๋จผ์ € ๊ณ„์‚ฐ๋˜์–ด์•ผ ํฐ ๋ฌธ์ œ์— ์“ธ ์ˆ˜ ์žˆ์–ด.
5
์ตœ์ข… ๋‹ต ์ถ”์ถœํ•˜๊ธฐ
dp ํ…Œ์ด๋ธ”์—์„œ ์›ํ•˜๋Š” ๋‹ต์ด ์–ด๋””์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ด.
dp[n], dp[n][m] ๋“ฑ ๋ฌธ์ œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ ธ.
๐ŸŽฏ DP vs ๋‹ค๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŒจ๋Ÿฌ๋‹ค์ž„
ํŒจ๋Ÿฌ๋‹ค์ž„ํ•ต์‹ฌ ์•„์ด๋””์–ด์ ์šฉ ์กฐ๊ฑด์˜ˆ์‹œ
๋™์ ๊ณ„ํš๋ฒ•์ค‘๋ณต ๋ถ€๋ถ„ ๋ฌธ์ œ ์ €์žฅยท์žฌํ™œ์šฉ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ + ์ค‘๋ณต ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฐฐ๋‚ญ, LCS, LIS
๋ถ„ํ• ์ •๋ณต๋ฌธ์ œ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋ถ„ํ• ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋…๋ฆฝ์ ๋ณ‘ํ•ฉ ์ •๋ ฌ, ํ€ต ์ •๋ ฌ
ํƒ์š• ์•Œ๊ณ ๋ฆฌ์ฆ˜๋งค ์ˆœ๊ฐ„ ์ตœ์„ ์˜ ์„ ํƒํƒ์š• ์„ ํƒ ์†์„ฑ ์„ฑ๋ฆฝ๋‹ค์ต์ŠคํŠธ๋ผ, ํ—ˆํ”„๋งŒ
์™„์ „ ํƒ์ƒ‰๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜ ํƒ์ƒ‰ํ•ญ์ƒ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋А๋ฆผ๋ธŒ๋ฃจํŠธ ํฌ์Šค

๐ŸŒŸ 9. ๊ณ ๊ธ‰ DP ๊ธฐ๋ฒ•๋“ค

๊ธฐ๋ณธ์„ ๋งˆ์Šคํ„ฐํ–ˆ๋‹ค๋ฉด ์ด์ œ ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•๋“ค์„ ์‚ดํŽด๋ณด์ž! ๐Ÿ”ฅ
์ด ๊ธฐ๋ฒ•๋“ค์€ ๊ฒฝ์Ÿ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‚˜ ๊ณ ๊ธ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ˆ˜์—…์—์„œ ์ž์ฃผ ๋“ฑ์žฅํ•ด.

๐ŸŽญ ๋น„ํŠธ๋งˆ์Šคํฌ DP

์ƒํƒœ๋ฅผ ๋น„ํŠธ(0๊ณผ 1)๋กœ ํ‘œํ˜„ํ•ด์„œ ์ง‘ํ•ฉ์„ ํšจ์œจ์ ์œผ๋กœ ๋‹ค๋ฃจ๋Š” ๊ธฐ๋ฒ•์ด์•ผ.
๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์™ธํŒ์› ์ˆœํšŒ(TSP, Traveling Salesman Problem)์•ผ!

n๊ฐœ์˜ ๋„์‹œ๋ฅผ ๋ชจ๋‘ ๋ฐฉ๋ฌธํ•˜๊ณ  ์ถœ๋ฐœ์ง€๋กœ ๋Œ์•„์˜ค๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋ผ.
์™„์ „ ํƒ์ƒ‰: O(n!) โ†’ ๋น„ํŠธ๋งˆ์Šคํฌ DP: O(2โฟ ร— nยฒ) โ€” ํ›จ์”ฌ ๋น ๋ฆ„!
# TSP ๋น„ํŠธ๋งˆ์Šคํฌ DP
# dp[visited][ํ˜„์žฌ๋„์‹œ] = ๋ฐฉ๋ฌธํ•œ ๋„์‹œ ์ง‘ํ•ฉ์ด visited์ด๊ณ 
#                         ํ˜„์žฌ ๋„์‹œ์— ์žˆ์„ ๋•Œ์˜ ์ตœ์†Œ ๋น„์šฉ

def tsp(dist, n):
    INF = float('inf')
    dp = [[INF] * n for _ in range(1 << n)]
    dp[1][0] = 0  # ๋„์‹œ 0์—์„œ ์‹œ์ž‘, ๋„์‹œ 0๋งŒ ๋ฐฉ๋ฌธ
    
    for visited in range(1 << n):
        for cur in range(n):
            if dp[visited][cur] == INF:
                continue
            for next_city in range(n):
                if visited & (1 << next_city):  # ์ด๋ฏธ ๋ฐฉ๋ฌธ
                    continue
                next_visited = visited | (1 << next_city)
                dp[next_visited][next_city] = min(
                    dp[next_visited][next_city],
                    dp[visited][cur] + dist[cur][next_city]
                )
    
    # ๋ชจ๋“  ๋„์‹œ ๋ฐฉ๋ฌธ ํ›„ ์ถœ๋ฐœ์ง€๋กœ ๋ณต๊ท€
    all_visited = (1 << n) - 1
    return min(dp[all_visited][i] + dist[i][0] for i in range(n))
๐Ÿ”ข ๊ตฌ๊ฐ„ DP (Interval DP)

๊ตฌ๊ฐ„ [i, j]์— ๋Œ€ํ•œ ์ตœ์ ํ•ด๋ฅผ ๊ตฌํ•˜๋Š” DP์•ผ.
๋Œ€ํ‘œ ๋ฌธ์ œ: ํ–‰๋ ฌ ์—ฐ์‡„ ๊ณฑ์…ˆ(Matrix Chain Multiplication)

์ ํ™”์‹: dp[i][j] = min(dp[i][k] + dp[k+1][j] + cost(i,k,j)) for k in [i, j-1] ๊ตฌ๊ฐ„ [i,j]๋ฅผ k์—์„œ ๋ถ„ํ• ํ•ด์„œ ์ตœ์  ๋น„์šฉ์„ ๊ตฌํ•จ

ํ–‰๋ ฌ Aโ‚ ร— Aโ‚‚ ร— Aโ‚ƒ ร— Aโ‚„๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ์–ด๋–ค ์ˆœ์„œ๋กœ ๊ณฑํ•˜๋А๋ƒ์— ๋”ฐ๋ผ
์—ฐ์‚ฐ ํšŸ์ˆ˜๊ฐ€ ์—„์ฒญ๋‚˜๊ฒŒ ๋‹ฌ๋ผ์ ธ. DP๋กœ ์ตœ์  ์ˆœ์„œ๋ฅผ O(nยณ)์— ์ฐพ์„ ์ˆ˜ ์žˆ์–ด!

๐Ÿ“Š DP ์ตœ์ ํ™” ๊ธฐ๋ฒ•๋“ค

๊ธฐ๋ฒ• 1 ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ์ตœ์ ํ™” ์ ํ™”์‹์ด ํŠน์ • ๋ฒ”์œ„์˜ ์ตœ์†Ÿ๊ฐ’/์ตœ๋Œ“๊ฐ’์— ์˜์กดํ•  ๋•Œ ๋ฑ(Deque)์„ ํ™œ์šฉํ•ด O(n)์œผ๋กœ ์ตœ์ ํ™”


๊ธฐ๋ฒ• 2 ๋ถ„ํ•  ์ •๋ณต ์ตœ์ ํ™”
์ ํ™”์‹์˜ ์ตœ์  ๋ถ„ํ• ์ ์ด ๋‹จ์กฐ ์ฆ๊ฐ€ํ•  ๋•Œ O(nยฒ log n) โ†’ O(n log n)์œผ๋กœ ์ตœ์ ํ™”


๊ธฐ๋ฒ• 3 ๋ณผ๋ก ๊ป์งˆ ํŠธ๋ฆญ (CHT)
์ ํ™”์‹์ด ์„ ํ˜• ํ•จ์ˆ˜์˜ ์ตœ์†Ÿ๊ฐ’ ํ˜•ํƒœ์ผ ๋•Œ O(nยฒ) โ†’ O(n)์œผ๋กœ ์ตœ์ ํ™”


๊ธฐ๋ฒ• 4 ๊ณต๊ฐ„ ์ตœ์ ํ™”
2D DP๋ฅผ 1D๋กœ ์ค„์ด๊ฑฐ๋‚˜, ๋กค๋ง ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ


๐ŸŒ 10. ์‹ค์ƒํ™œ์—์„œ์˜ DP ์‘์šฉ

DP๋Š” ์ด๋ก ์—๋งŒ ๋จธ๋ฌผ์ง€ ์•Š์•„. ์šฐ๋ฆฌ ์ผ์ƒ ๊ณณ๊ณณ์— ์ˆจ์–ด์žˆ์–ด! ๐Ÿ‘€

๋™์ ๊ณ„ํš๋ฒ•์ด ์ˆจ์–ด์žˆ๋Š” ์‹ค์ƒํ™œ ๋ถ„์•ผ ๋™์  ๊ณ„ํš๋ฒ• ๐Ÿ—บ๏ธ ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ ๋‹ค์ต์ŠคํŠธ๋ผ/๋ฒจ๋งŒํฌ๋“œ ๐Ÿงฌ ์ƒ๋ฌผ์ •๋ณดํ•™ DNA ์„œ์—ด ์ •๋ ฌ LCS ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๐Ÿ’น ๊ธˆ์œต ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์ ํ™” ์˜ต์…˜ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ ๐Ÿค– AI/ML ๊ฐ•ํ™”ํ•™์Šต ์Œ์„ฑ ์ธ์‹(๋น„ํ„ฐ๋น„) ๐ŸŽฎ ๊ฒŒ์ž„ NPC ๊ฒฝ๋กœ ํƒ์ƒ‰ ๊ฒŒ์ž„ AI ์ „๋žต ๐Ÿ“ ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ ๋งž์ถค๋ฒ• ๊ต์ • ํŽธ์ง‘ ๊ฑฐ๋ฆฌ(Edit Distance)
๐Ÿ“ฑ ํŽธ์ง‘ ๊ฑฐ๋ฆฌ (Edit Distance)

๋‘ ๋ฌธ์ž์—ด ์‚ฌ์ด์˜ ํŽธ์ง‘ ๊ฑฐ๋ฆฌ(Levenshtein Distance)๋Š” ๋งž์ถค๋ฒ• ๊ต์ •, ๊ฒ€์ƒ‰ ์—”์ง„, ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ์— ํ•ต์‹ฌ์ ์œผ๋กœ ์“ฐ์—ฌ.
ํ•œ ๋ฌธ์ž์—ด์„ ๋‹ค๋ฅธ ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•œ ์ตœ์†Œ ํŽธ์ง‘ ํšŸ์ˆ˜(์‚ฝ์ž…, ์‚ญ์ œ, ๊ต์ฒด)๋ฅผ ๊ตฌํ•˜๋Š” ๊ฑฐ์•ผ.

์ ํ™”์‹: X[i] == Y[j]์ด๋ฉด: dp[i][j] = dp[i-1][j-1]
X[i] != Y[j]์ด๋ฉด: dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
โ†’ ๊ฐ๊ฐ ์‚ญ์ œ, ์‚ฝ์ž…, ๊ต์ฒด์— ํ•ด๋‹น

์˜ˆ๋ฅผ ๋“ค์–ด "kitten"๊ณผ "sitting"์˜ ํŽธ์ง‘ ๊ฑฐ๋ฆฌ๋Š” 3์ด์•ผ.
์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋•๋ถ„์— ์šฐ๋ฆฌ๊ฐ€ ์˜คํƒ€๋ฅผ ์ณ๋„ ๊ฒ€์ƒ‰ ์—”์ง„์ด "ํ˜น์‹œ ์ด๊ฑธ ์ฐพ์œผ์…จ๋‚˜์š”?"๋ผ๊ณ  ์ œ์•ˆํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์•ผ! ๐Ÿ”

๐ŸŽต ๋น„ํ„ฐ๋น„ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Viterbi Algorithm)

์Œ์„ฑ ์ธ์‹, ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ์—์„œ ์“ฐ์ด๋Š” DP ๊ธฐ๋ฐ˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์•ผ.
์€๋‹‰ ๋งˆ๋ฅด์ฝ”ํ”„ ๋ชจ๋ธ(HMM)์—์„œ ๊ฐ€์žฅ ๊ฐ€๋Šฅ์„ฑ ๋†’์€ ์ƒํƒœ ์‹œํ€€์Šค๋ฅผ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋ผ.
์Šค๋งˆํŠธํฐ์˜ ์Œ์„ฑ ์ธ์‹, ์ž๋™ ๋ฒˆ์—ญ ๋“ฑ์— ํ•ต์‹ฌ์ ์œผ๋กœ ํ™œ์šฉ๋˜๋Š” ๊ธฐ์ˆ ์ด์•ผ!


๐Ÿง  11. DP์˜ ์ˆ˜ํ•™์  ๊ธฐ๋ฐ˜

DP๋Š” ๋‹จ์ˆœํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด ์•„๋‹ˆ์•ผ. ํƒ„ํƒ„ํ•œ ์ˆ˜ํ•™์  ๊ธฐ๋ฐ˜ ์œ„์— ์„œ ์žˆ์–ด.

๐Ÿ“ ๋ฒจ๋งŒ ๋ฐฉ์ •์‹ (Bellman Equation)

๊ฐ•ํ™”ํ•™์Šต์˜ ํ•ต์‹ฌ์ด๊ธฐ๋„ ํ•œ ๋ฒจ๋งŒ ๋ฐฉ์ •์‹์€ DP์˜ ์ˆ˜ํ•™์  ํ‘œํ˜„์ด์•ผ:

V*(s) = max_a [R(s,a) + ฮณ ยท ฮฃ P(s'|s,a) ยท V*(s')] V*(s): ์ƒํƒœ s์—์„œ์˜ ์ตœ์  ๊ฐ€์น˜
R(s,a): ํ–‰๋™ a๋ฅผ ํ–ˆ์„ ๋•Œ ๋ฐ›๋Š” ๋ณด์ƒ
ฮณ: ํ• ์ธ์œจ (๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ˜„์žฌ ๊ฐ€์น˜)
P(s'|s,a): ์ƒํƒœ ์ „์ด ํ™•๋ฅ 

์ด ๋ฐฉ์ •์‹์ด ๋ฐ”๋กœ ํ˜„๋Œ€ AI์˜ ๊ฐ•ํ™”ํ•™์Šต(Reinforcement Learning)์˜ ๊ทผ๊ฐ„์ด์•ผ.
์•ŒํŒŒ๊ณ (AlphaGo)๋„ ์ด ์›๋ฆฌ๋ฅผ ํ™œ์šฉํ–ˆ์–ด! ๐Ÿค–

๐Ÿ“Š ๋ณต์žก๋„ ๋ถ„์„
๋ฌธ์ œ์™„์ „ ํƒ์ƒ‰DP ์‹œ๊ฐ„DP ๊ณต๊ฐ„
ํ”ผ๋ณด๋‚˜์น˜O(2โฟ)O(n)O(1)~O(n)
๋ฐฐ๋‚ญ ๋ฌธ์ œO(2โฟ)O(nW)O(nW)
LCSO(2โฟ)O(mn)O(mn)
LISO(2โฟ)O(nยฒ)O(n)
ํ”Œ๋กœ์ด๋“œ-์›Œ์…œO(n!)O(nยณ)O(nยฒ)
TSP (๋น„ํŠธ๋งˆ์Šคํฌ)O(n!)O(2โฟยทnยฒ)O(2โฟยทn)

ํ‘œ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, DP๋Š” ์ง€์ˆ˜ ์‹œ๊ฐ„์ด๋‚˜ ํŒฉํ† ๋ฆฌ์–ผ ์‹œ๊ฐ„์„ ๋‹คํ•ญ ์‹œ๊ฐ„ ๋˜๋Š” ์ง€์ˆ˜ ์‹œ๊ฐ„์˜ ๋” ๋‚ฎ์€ ์ฐจ์ˆ˜๋กœ ์ค„์—ฌ์ค˜.
์ด๊ฒŒ DP๊ฐ€ ๊ทธํ† ๋ก ๊ฐ•๋ ฅํ•œ ์ด์œ ์•ผ!


๐ŸŽ“ 12. DP ๋งˆ์Šคํ„ฐ๋ฅผ ์œ„ํ•œ ํ•™์Šต ๋กœ๋“œ๋งต

DP๋ฅผ ์ œ๋Œ€๋กœ ๋งˆ์Šคํ„ฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋Ÿฐ ์ˆœ์„œ๋กœ ๊ณต๋ถ€ํ•˜๋Š” ๊ฑธ ์ถ”์ฒœํ•ด!

1
๊ธฐ์ดˆ ๋‹จ๊ณ„ โ€” ํ”ผ๋ณด๋‚˜์น˜, ๊ณ„๋‹จ ์˜ค๋ฅด๊ธฐ, ํƒ€์ผ๋ง ๋ฌธ์ œ
๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฐ”ํ…€์—… 1D DP
2
์ค‘๊ธ‰ ๋‹จ๊ณ„ โ€” ๋ฐฐ๋‚ญ ๋ฌธ์ œ, LCS, LIS, ํŽธ์ง‘ ๊ฑฐ๋ฆฌ
2D DP ์ ํ™”์‹ ์„ค๊ณ„ ๊ณต๊ฐ„ ์ตœ์ ํ™”
3
๊ณ ๊ธ‰ ๋‹จ๊ณ„ โ€” ๋น„ํŠธ๋งˆ์Šคํฌ DP, ๊ตฌ๊ฐ„ DP, ํŠธ๋ฆฌ DP
๋น„ํŠธ๋งˆ์Šคํฌ ๊ตฌ๊ฐ„ DP TSP
4
์ตœ์ ํ™” ๋‹จ๊ณ„ โ€” CHT, ๋ถ„ํ• ์ •๋ณต ์ตœ์ ํ™”, ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ
CHT ๋ถ„ํ• ์ •๋ณต ์ตœ์ ํ™” ๋‹จ์กฐ ๋ฑ

์ฐธ๊ณ ๋กœ, ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ์ˆ˜ํ•™ ์‹ค๋ ฅ์„ ํ‚ค์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด ์žฌ๋Šฅ๋„ท(jaenung.net)์—์„œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŠœํ„ฐ๋ง ์žฌ๋Šฅ์„ ์ฐพ์•„๋ณผ ์ˆ˜๋„ ์žˆ์–ด!
๋‹ค์–‘ํ•œ ์ „๋ฌธ๊ฐ€๋“ค์ด DP๋ฅผ ํฌํ•จํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ 1:1๋กœ ๊ฐ€๋ฅด์ณ์ฃผ๋Š” ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ฑฐ๋“ . ํ˜ผ์ž ๊ณต๋ถ€ํ•˜๋‹ค ๋ง‰ํžˆ๋ฉด ์ „๋ฌธ๊ฐ€์˜ ๋„์›€์„ ๋ฐ›๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ ๐Ÿ˜Š

๐Ÿ’ก DP ๋ฌธ์ œ ํ’€ ๋•Œ ํ”ํžˆ ํ•˜๋Š” ์‹ค์ˆ˜๋“ค

โŒ ์ƒํƒœ ์ •์˜๋ฅผ ๋ชจํ˜ธํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ dp[i]๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์œผ๋ฉด ์ ํ™”์‹์„ ์„ธ์šธ ์ˆ˜ ์—†์–ด.


โŒ ์ดˆ๊ธฐ๊ฐ’(Base Case)์„ ๋น ๋œจ๋ฆฌ๋Š” ๊ฒƒ
dp[0]์ด๋‚˜ dp[1] ๊ฐ™์€ ๊ธฐ์ € ์‚ฌ๋ก€๋ฅผ ์ž˜๋ชป ์„ค์ •ํ•˜๋ฉด ์ „์ฒด ๊ฒฐ๊ณผ๊ฐ€ ํ‹€๋ ค.


โŒ ๊ณ„์‚ฐ ์ˆœ์„œ๋ฅผ ์ž˜๋ชป ์žก๋Š” ๊ฒƒ
๋ฐ”ํ…€์—…์—์„œ dp[i]๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ํ•„์š”ํ•œ dp[j](j < i)๊ฐ€ ์•„์ง ๊ณ„์‚ฐ ์•ˆ ๋์œผ๋ฉด ์•ˆ ๋ผ.


โŒ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š” ๊ฒƒ
2D DP ๋ฐฐ์—ด์ด ๋„ˆ๋ฌด ํฌ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์–ด. ๊ณต๊ฐ„ ์ตœ์ ํ™”๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•ด.


๐Ÿ”ฅ 13. ์‹ค์ „ ๋ฌธ์ œ โ€” ๊ณ„๋‹จ ์˜ค๋ฅด๊ธฐ

๋งˆ์ง€๋ง‰์œผ๋กœ ์™„์ „ํ•œ DP ๋ฌธ์ œ ํ•˜๋‚˜๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ’€์–ด๋ณด์ž!

n๊ฐœ์˜ ๊ณ„๋‹จ์ด ์žˆ์–ด. ํ•œ ๋ฒˆ์— 1์นธ ๋˜๋Š” 2์นธ์”ฉ ์˜ค๋ฅผ ์ˆ˜ ์žˆ์„ ๋•Œ,
n๋ฒˆ์งธ ๊ณ„๋‹จ์— ์˜ค๋ฅด๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋Š”?
๐Ÿ” ํ’€์ด ๊ณผ์ •
1
์ƒํƒœ ์ •์˜: dp[i] = i๋ฒˆ์งธ ๊ณ„๋‹จ์— ์˜ค๋ฅด๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜
2
์ ํ™”์‹: dp[i] = dp[i-1] + dp[i-2]
(i-1๋ฒˆ์งธ์—์„œ 1์นธ ์˜ค๋ฅด๊ฑฐ๋‚˜, i-2๋ฒˆ์งธ์—์„œ 2์นธ ์˜ค๋ฅด๊ฑฐ๋‚˜)
3
์ดˆ๊ธฐ๊ฐ’: dp[1] = 1, dp[2] = 2
4
๊ณ„์‚ฐ ์ˆœ์„œ: i = 3, 4, 5, ... n ์ˆœ์„œ๋กœ
5
์ตœ์ข… ๋‹ต: dp[n]
def climb_stairs(n):
    if n <= 2:
        return n
    dp = [0] * (n + 1)
    dp[1] = 1
    dp[2] = 2
    for i in range(3, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

# ํ…Œ์ŠคํŠธ
for i in range(1, 8):
    print(f"๊ณ„๋‹จ {i}๊ฐœ: {climb_stairs(i)}๊ฐ€์ง€")
# ์ถœ๋ ฅ:
# ๊ณ„๋‹จ 1๊ฐœ: 1๊ฐ€์ง€
# ๊ณ„๋‹จ 2๊ฐœ: 2๊ฐ€์ง€
# ๊ณ„๋‹จ 3๊ฐœ: 3๊ฐ€์ง€
# ๊ณ„๋‹จ 4๊ฐœ: 5๊ฐ€์ง€
# ๊ณ„๋‹จ 5๊ฐœ: 8๊ฐ€์ง€
# ๊ณ„๋‹จ 6๊ฐœ: 13๊ฐ€์ง€
# ๊ณ„๋‹จ 7๊ฐœ: 21๊ฐ€์ง€

๋ˆˆ์น˜์ฑ˜์–ด? ๊ฒฐ๊ณผ๊ฐ€ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์ด์•ผ! ๐Ÿคฉ
์ด๋ ‡๊ฒŒ DP ๋ฌธ์ œ๋“ค์€ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ , ๊ฐ™์€ ํŒจํ„ด์ด ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚˜.
์ด ํŒจํ„ด์„ ์ธ์‹ํ•˜๋Š” ๋Šฅ๋ ฅ์ด ๋ฐ”๋กœ DP ๋งˆ์Šคํ„ฐ์˜ ํ•ต์‹ฌ์ด์•ผ!

๊ทธ๋ฆฌ๊ณ  ์žฌ๋Šฅ๋„ท์—์„œ ์ˆ˜ํ•™์ด๋‚˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ด€๋ จ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ๊ธฐ์–ตํ•ด์ค˜.
DP ๊ฐ™์€ ์–ด๋ ค์šด ๊ฐœ๋…๋„ ์ข‹์€ ์„ ์ƒ๋‹˜๊ณผ ํ•จ๊ป˜๋ผ๋ฉด ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ! ๐ŸŽฏ


๐ŸŽฏ 14. ์ •๋ฆฌ โ€” DP์˜ ํ•ต์‹ฌ ์ฒ ํ•™
๋™์ ๊ณ„ํš๋ฒ• ํ•ต์‹ฌ ์š”์•ฝ ๐Ÿงฉ ๐Ÿ”„ ์ค‘๋ณต ๊ณ„์‚ฐ ์ œ๊ฑฐ ๊ฐ™์€ ๊ณ„์‚ฐ์€ ํ•œ ๋ฒˆ๋งŒ! ๐Ÿ“ฆ ๊ฒฐ๊ณผ ์ €์žฅยท์žฌํ™œ์šฉ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฐ”ํ…€์—… ํ…Œ์ด๋ธ” ๐Ÿงฉ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ ์ž‘์€ ์ตœ์ ํ•ด๊ฐ€ ํฐ ์ตœ์ ํ•ด๋ฅผ ๊ตฌ์„ฑ โšก ๊ทน์ ์ธ ํšจ์œจ ์ง€์ˆ˜ โ†’ ๋‹คํ•ญ ์‹œ๊ฐ„ ๋ณต์žก๋„ ๐Ÿ’ฌ DP์˜ ํ•ต์‹ฌ ์ฒ ํ•™ "๊ณผ๊ฑฐ์˜ ์ง€ํ˜œ๋ฅผ ๊ธฐ์–ตํ•˜๊ณ , ํ˜„์žฌ์˜ ๊ฒฐ์ •์— ํ™œ์šฉํ•˜๋ผ." ์ด๋ฏธ ํ’€์–ด๋ณธ ๋ฌธ์ œ๋Š” ๋‹ค์‹œ ํ’€์ง€ ์•Š๋Š”๋‹ค โ€” ์ด๊ฒƒ์ด DP์˜ ๋ณธ์งˆ์ด๋‹ค.

์ž, ์ด์ œ ๋™์ ๊ณ„ํš๋ฒ•์˜ ์„ธ๊ณ„๋ฅผ ๊ฝค ๊นŠ์ด ํƒํ—˜ํ–ˆ์–ด! ๐ŸŽ‰
์ฒ˜์Œ์—” ์ด๋ฆ„๋ถ€ํ„ฐ ๋ฌด์„œ์› ๋˜ DP๊ฐ€ ์ด์ œ ์ข€ ์นœ๊ทผํ•˜๊ฒŒ ๋А๊ปด์ง€์ง€ ์•Š์•„?

DP์˜ ํ•ต์‹ฌ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•˜๋ฉด:

โœ… ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๋กœ ์ชผ๊ฐœ๊ธฐ โ€” ๋ถ„ํ• ์˜ ๊ธฐ์ˆ 

โœ… ์ด๋ฏธ ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋Š” ์ €์žฅํ•˜๊ธฐ โ€” ๋ฉ”๋ชจ์ด์ œ์ด์…˜์˜ ์ง€ํ˜œ

โœ… ์ž‘์€ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ํ’€๊ธฐ โ€” ๋ฐ”ํ…€์—…์˜ ์ฒด๊ณ„์„ฑ

โœ… ์ ํ™”์‹์„ ํ†ตํ•ด ๊ด€๊ณ„ ํ‘œํ˜„ํ•˜๊ธฐ โ€” ์ˆ˜ํ•™์  ์šฐ์•„ํ•จ

โœ… ์ง€์ˆ˜ ์‹œ๊ฐ„์„ ๋‹คํ•ญ ์‹œ๊ฐ„์œผ๋กœ ์ค„์ด๊ธฐ โ€” ํšจ์œจ์˜ ๋งˆ๋ฒ•

DP๋Š” ๋‹จ์ˆœํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋ฒ•์„ ๋„˜์–ด์„œ ๋ฌธ์ œ๋ฅผ ๋ฐ”๋ผ๋ณด๋Š” ์‚ฌ๊ณ ๋ฐฉ์‹์ด์•ผ.
"์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ชผ๊ฐค ์ˆ˜ ์žˆ์„๊นŒ?", "์–ด๋–ค ์ •๋ณด๋ฅผ ์ €์žฅํ•ด๋‘๋ฉด ๋‚˜์ค‘์— ์“ธ ์ˆ˜ ์žˆ์„๊นŒ?"
์ด๋Ÿฐ ์งˆ๋ฌธ์„ ์Šต๊ด€์ ์œผ๋กœ ๋˜์ง€๋‹ค ๋ณด๋ฉด ์–ด๋А์ƒˆ DP ๋งˆ์Šคํ„ฐ๊ฐ€ ๋˜์–ด ์žˆ์„ ๊ฑฐ์•ผ! ๐Ÿ’ช

์ˆ˜ํ•™๊ณผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์„ธ๊ณ„๋Š” ๊นŠ๊ณ  ๋„“์–ด. ์˜ค๋Š˜ ๋ฐฐ์šด DP๋Š” ๊ทธ ์„ธ๊ณ„์˜ ์•„์ฃผ ์ค‘์š”ํ•œ ๋ฌธ ํ•˜๋‚˜๋ฅผ ์—ฐ ๊ฑฐ์•ผ.
๊ณ„์† ํƒํ—˜ํ•˜๊ณ , ๊ณ„์† ์งˆ๋ฌธํ•˜๊ณ , ๊ณ„์† ์„ฑ์žฅํ•ด! ๐Ÿš€

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.