μλ νμΈμ μ μΈμ λλ€!
μ€λμ μκ³ λ¦¬μ¦ κ°λ μ€ λμ κ³νλ²(Dynamic Programming)μ λν΄ μ 리ν΄λ³΄λ €κ³ ν©λλ€.
λμ κ³νλ²μ΄ 무μμΈμ§ μ 리ν΄λ³΄κ³ , λμ κ³νλ²μ λνμ μΈ μμ μΈ <νΌλ³΄λμΉ μμ΄> λ¬Έμ λ₯Ό ν΅ν΄ μ μ©κΉμ§ ν΄λ³΄λλ‘ ν κ²μ!
λμ κ³νλ²(Dynamic Programming, DP)
λ€μ΄λλ―Ή νλ‘κ·Έλλ°(μ€μ¬μ DP)λΌκ³ λ λΆλ¦¬λ λμ κ³νλ²μ ν° λ¬Έμ λ₯Ό μκ² λλκ³ , κ°μ λ¬Έμ λΌλ©΄ ν λ²μ©λ§ νμ΄ λ¬Έμ λ₯Ό ν¨μ¨μ μΌλ‘ ν΄κ²°νλ μκ³ λ¦¬μ¦ κΈ°λ²μ λλ€.
λμ κ³νλ²μμλ λ©λͺ¨μ΄μ μ΄μ (Memoization) κΈ°λ²μ΄ ν΅μ¬μ΄λΌκ³ ν μ μλλ°μ!
λ©λͺ¨μ΄μ μ΄μ κΈ°λ²μ΄λ, ν λ² κ΅¬ν κ²°κ³Όλ₯Ό λ©λͺ¨λ¦¬ 곡κ°μ μ μ₯ν΄λκ³ κ°μ μμ λ€μ νΈμΆν΄ μ μ₯ν κ²°κ³Όλ₯Ό κ·Έλλ‘ κ°μ Έμ€λ κΈ°λ²μ μλ―Έν©λλ€. λ©λͺ¨μ΄μ μ΄μ μ κ°μ μ μ₯νλ λ°©λ²μ΄λ―λ‘ μΊμ±(Caching)μ΄λΌκ³ λ ν©λλ€.
λμ κ³νλ²μ λ©λͺ¨μ΄μ μ΄μ κΈ°λ²μ νμ©ν΄ λμΌν κ³μ°μ λ°λ³΅ν΄μΌν λ, μ΄μ μ κ³μ°ν κ°μ λ©λͺ¨λ¦¬μ μ μ₯νμ¬ λ°λ³΅ μνμ μ κ±°νμ¬ νλ‘κ·Έλ¨ μ€ν μλλ₯Ό λΉ λ₯΄κ² νκΈ° λλ¬Έμ λ©λͺ¨λ¦¬ 곡κ°μ μ½κ° λ μ¬μ©νλ©΄μ μ°μ° μλλ₯Ό λΉμ½μ μΌλ‘ μ¦κ°μν¬ μ μλ λ°©λ²μ λλ€.
λμ κ³νλ²μΌλ‘ ν΄κ²°ν μ μλ λνμ μΈ μμ μΈ <νΌλ³΄λμΉ μμ΄>μ ν΅ν΄μ λ μμΈν μ΄ν΄ν΄λ³΄λλ‘ ν©μλ€!
νΌλ³΄λμΉ μμ΄λ‘ λμ κ³νλ²μ μ΄ν΄ν΄λ³΄μ
νΌλ³΄λμΉ μμ΄μ΄λ, μ΄λ€ μμ΄μ νμ΄ μμ λ νμ ν©κ³Ό κ°μ μμ΄μ λ§ν©λλ€.
νΌλ³΄λμΉ μμ΄μ κ°λ¨νκ² νμ©ν λ¬Έμ μΈ νλ‘κ·Έλλ¨Έμ€μ νΌλ³΄λμΉ μ λ¬Έμ λ₯Ό νμ΄λ³΄λ©° λμ κ³νλ²μ μ΄ν΄ν΄λ³΄λλ‘ ν κ²μ!
λ¬Έμ μ€λͺ
νΌλ³΄λμΉ μλ F(0) = 0, F(1) = 1μΌ λ, 1 μ΄μμ nμ λνμ¬ F(n) = F(n-1) + F(n-2) κ° μ μ©λλ μ μ λλ€.
μλ₯Όλ€μ΄
- F(2) = F(0) + F(1) = 0 + 1 = 1
- F(3) = F(1) + F(2) = 1 + 1 = 2
- F(4) = F(2) + F(3) = 1 + 2 = 3
- F(5) = F(3) + F(4) = 2 + 3 = 5
μ κ°μ΄ μ΄μ΄μ§λλ€.
2 μ΄μμ nμ΄ μ λ ₯λμμ λ, nλ²μ§Έ νΌλ³΄λμΉ μλ₯Ό 1234567μΌλ‘ λλ λλ¨Έμ§λ₯Ό 리ν΄νλ ν¨μ, solutionμ μμ±ν΄ μ£ΌμΈμ.
μ ν μ¬ν
- nμ 2 μ΄μ 100,000 μ΄νμΈ μμ°μμ λλ€.
μ μΆλ ₯ μμ λ° μ€λͺ
n | return |
3 | 2 |
5 | 5 |
νΌλ³΄λμΉμλ 0λ²μ§ΈλΆν° 0, 1, 1, 2, 3, 5, ... μ κ°μ΄ μ΄μ΄μ§λλ€.
λ¬Έμ νμ΄
1. μ¬κ·ν¨μλ₯Ό μ΄μ©ν ꡬν
νλ‘κ·Έλλ¨Έμ€ Level2 λμ΄λμΈ μ΄ λ¬Έμ λ nλ²μ§Έ νΌλ³΄λμΉ μλ₯Ό ꡬνλλ°, μ΄ μλ₯Ό 1234567μΌλ‘ λλ λλ¨Έμ§λ₯Ό ꡬνλΌλ μ‘°κ±΄λ§ μΆκ°λ λ¬Έμ μΈλ°μ! λ¨Όμ , μ¬κ·ν¨μλ₯Ό μ΄μ©ν΄ λ¬Έμ λ₯Ό νμ΄λ³Έλ€λ©΄
func solution(_ n: Int) -> Int {
if n <= 1 {
return n
} else {
return (solution(n-1) + solution(n-2)) % 1234567
}
}
μμ κ°μ΄ κ°λ¨νκ² κ΅¬νν μ μμ΅λλ€!
νμ§λ§.. λ¬Έμ λ..ν¨μ¨μ± μΈ‘λ©΄μμ μ’μ§ λͺ»ν μ½λλΌλ μ μ λλ€!(μκ°μ΄κ³Όκ° μλ₯΄λ₯΄π₯²)
μ΄λ κ² μ¬κ·ν¨μλ₯Ό μ΄μ©ν΄ ꡬννλ νμ΄κ° μ μκ°μ΄ μ€λ걸리λ νμ΄μΌκΉμ??π€
λ§μ½ 4λ²μ§Έ νΌλ³΄λμΉ μλ₯Ό 1234567μΌλ‘ λλ λλ¨Έμ§λ₯Ό ꡬνκΈ° μν΄ solution(4)λ₯Ό μ€ννλ©΄,
μλμ κ·Έλ¦Όκ³Ό κ°μ ννλ‘ ν¨μκ° νΈμΆλκ² λ©λλ€.
κ·Έλ¦Όμ 보면 λμΌν ν¨μκ° λ°λ³΅μ μΌλ‘ νΈμΆλλ κ²μ νμΈν μ μμ΅λλ€. μ΄λ―Έ ν λ² κ³μ°νμ§λ§, κ³μ νΈμΆλ λ λ§λ€ λμΌν κ°μ΄ κ³μ°λκ² λλ κ²μ λλ€. μμ κ·Έλ¦Όμμ soultion(1)μ μ΄ 3λ² νΈμΆλμμ΅λλ€. solution(n)μμ nκ°μ΄ 컀μ§λ©΄ 컀μ§μλ‘ μ€λ³΅ νΈμΆλλ ν¨μμ μ€λ³΅ νμ λν λμ΄λκ² λλλ°, μ΄λ nκ°μ΄ 컀μ§μ λ°λΌ νλ‘κ·Έλ¨ μ€ν μλκ° λ¨μ΄μ§λ€λ κ²μ μλ―Έν©λλ€.
2. λμ κ³νλ²μ μ΄μ©ν ꡬν
νΌλ³΄λμΉ μμ΄μ μ νμμ μμ κ°μ΄ μ¬κ· ν¨μλ₯Ό μ¬μ©ν΄ λ§λ€ μλ μμ§λ§, λ¨μν λ§€λ² κ³μ°νλλ‘ νκΈ° λλ¬Έμ λ¬Έμ λ₯Ό ν¨μ¨μ μΌλ‘ ν΄κ²°ν μ μλ€λ κ²μ νμΈνμ΅λλ€. μ΄λ¬ν λ¬Έμ λ λμ κ³νλ²μ μ΄μ©ν΄ ν΄κ²°ν μ μμ΅λλ€.
λ©λͺ¨μ΄μ μ΄μ κΈ°λ²μ νμ©ν΄ μ΄μ μ κ³μ°ν κ°μ λ©λͺ¨λ¦¬μ μ μ₯ν΄ λ°λ³΅ μνμ μ κ±°νλ λ°©μμΌλ‘ ꡬνν΄λ΄ μλ€!
func solution(_ n: Int) -> Int {
var cache = [0, 1]
for i in 2...n {
cache.append((cache[i-1] + cache[i-2]) % 1234567)
}
return cache[n]
}
μμ κ°μ΄ ꡬνν μ μλλ°μ, μ½λλ₯Ό 보면 cacheλΌλ Array μ μ₯ 곡κ°μ νμ©ν΄ (μ΄μ λ μμ ν© % 1234567)μΈ κ°μ μ μ₯ν΄λκ³ ,
μ€λ³΅ κ³μ° μμ΄ nλ²μ§Έ νΌλ³΄λμΉ μλ₯Ό 1234567μΌλ‘ λλ λλ¨Έμ§λ₯Ό ꡬνκ³ μμ΅λλ€. (κ·Έλ₯ nλ²μ§Έ νΌλ³΄λμΉ μλ₯Ό ꡬνκ³ μΆλ€λ©΄ for 루νμμ % 1234567 λΆλΆλ§ μμ ν΄μ£Όλ©΄ λκ² μ£ ?)
λ§μ½ solution(4)λ₯Ό μ€ννλ€λ©΄, (0, 1μ μ€ν μ μ΄κΈ°κ°μΌλ‘ cacheμ μ μ₯λλ) 2, 3λ²μ§Έ κ°κΉμ§λ₯Ό λ¨Όμ ꡬνμ¬ μ μ₯νκ³ , μ΄ κ°λ€μ΄ λͺ¨λ μ μ₯λμ΄μλ λ©λͺ¨λ¦¬μμ νμν κ°λ€μ κ°μ Έμ cache[2] + cache[3] μ°μ°μ ν΅ν΄ μ΅μ’ κ°μ λμΆνκ² λ©λλ€. μμμ μ¬κ·ν¨μλ‘ κ΅¬νν κ²κ³Ό λ¬λ¦¬ ν¨μμ μ€λ³΅ μ€νμ΄ μκΈ° λλ¬Έμ μ€ν μλκ° ν¨μ¬ λΉ¨λΌμ§κ² λ©λλ€.
λμ κ³νλ²μ μ¬μ© 쑰건
μμ λ₯Ό ν΅ν΄ μ¬κ·ν¨μ νμ΄μ λΉκ΅ν΄λ³΄λ μ΄μ λμ κ³νλ²μ΄ μ΄λ€ μκ³ λ¦¬μ¦ κΈ°λ²μΈμ§ κ°μ΄ μ€μμ£ ??
νμ§λ§ λͺ¨λ λ¬Έμ λ₯Ό λμ κ³νλ²μ μ μ©νμ¬ ν΄κ²°ν μλ μμ΅λλ€! λμ κ³νλ²μ λ€μ λ κ°μ§ 쑰건μ λ§μ‘±ν λ μ¬μ©ν μ μμ΅λλ€.
1. ν° λ¬Έμ λ₯Ό μμ λ¬Έμ λ‘ λλ μ μλ€.
2. μμ λ¬Έμ μμ ꡬν μ λ΅μ κ·Έκ²μ ν¬ν¨νλ ν° λ¬Έμ μμλ λμΌνλ€.
λμ κ³νλ²μ λ κ°μ§ λ°©μ
μμ <νΌλ³΄λμΉ μ> λ¬Έμ μμ μ μ©ν λμ κ³νλ²μ νμ΄ λ°©λ²μ λ°λ³΅λ¬Έμ μ΄μ©ν΄ μμ λ¬Έμ λΆν° λ΅μ λμΆν΄ μ΄λ₯Ό λ©λͺ¨λ¦¬μ μ μ₯ν΄λκ³ μ΄λ₯Ό μ΄μ©ν΄ ν° λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©μμ΄μμ΅λλ€. μ΄λ κ² λ°λ³΅λ¬Έμ μ΄μ©ν λ°©μμ μμ λ¬Έμ λΆν° μ°¨κ·Όμ°¨κ·Ό λ΅μ λμΆνλ€κ³ νμ¬ λ³΄ν μ (Bottom-Up) λ°©μμ΄λΌκ³ λ§ν©λλ€.
λμ κ³νλ²μλ 보ν μ λ°©μκ³Ό λλΆμ΄ νλ€μ΄(Top-Down) λ°©μλ μ‘΄μ¬ν©λλ€.
νλ€μ΄ λ°©μμ μ¬κ· ν¨μλ₯Ό μ΄μ©νμ¬ μμ€ μ½λλ₯Ό μμ±νλ λ°©μμΈλ°μ, ν° λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ μμ λ¬Έμ λ₯Ό νΈμΆνλ€κ³ νμ¬ νλ€μ΄ λ°©μμ΄λΌκ³ λ§ν©λλ€.
μμμ μ¬κ· ν¨μλ₯Ό μ΄μ©ν λ°©μμ μ€λ³΅ μ€νμ΄λΌλ λ¬Έμ λλ¬Έμ λμ κ³νλ²μ μ¬μ©ν΄ ν¨μ¨μ±μ κ°μ νλλ° μ΄κ² λ¬΄μ¨ μλ¦°κ°...νμ€ μ μμ κ² κ°μλ°μ! νλ€μ΄ λ°©μμ μ½λλ₯Ό ν λ² μ΄ν΄λ΄ μλ€!
var cache = Array(repeating: 0, count: 100001)
func solution(_ n: Int) -> Int {
// μ’
λ£ μ‘°κ±΄(1 or 2μΌ λ 1μ λ°ν)
if n == 1 || n == 2 {
return 1
}
// μ΄λ―Έ κ³μ°ν μ μλ λ¬Έμ λΌλ©΄ κ·Έλλ‘ λ°ν
if cache[n] != 0 {
return cache[n]
} else { // μμ§ κ³μ°νμ§ μμ λ¬Έμ μΌ λ μ νμμ λ°λΌ κ³μ°
cache[n] = (solution(n-1) + solution(n-2)) % 1234567
}
return cache[n]
}
μμμ λ³Έ μ¬κ·ν¨μλ₯Ό μ΄μ©ν νμ΄μ λ€λ₯Έ μ μ μ ν μ¬νμ μ μλ μ΅λκ°λ³΄λ€ 1λ§νΌ ν° ν¬κΈ°μ cacheλΌλ λ°°μ΄μ 0μΌλ‘ μ΄κΈ°νν΄λκ³ κ³μ°ν κ°μ μ°¨λ‘λ‘ cacheμλ€ μ μ₯ν΄μ λμ€μ λμΌν λ¬Έμ λ₯Ό κ³μ°ν΄μΌ ν λ, μ΄λ―Έ μ μ₯ν κ°μ λ°ννμ¬ ν¨μμ μ€λ³΅ νΈμΆμ΄ μλλ‘ νλ€λ μ μ λλ€! (μ€μ λ‘ μ΄ μ½λ λν νλ‘κ·Έλλ¨Έμ€μ μκ° μ νμ κ±Έλ¦¬μ§ μκ³ ν΅κ³Όλ©λλ€)
μ΄λ κ² νλ€μ΄ λ°©μκΉμ§ λμ κ³νλ²μ λ°©μ λ κ°μ§ λͺ¨λ μ΄ν΄λ³΄μλλ°μ, λμ κ³νλ²μ μ νμ μΈ ννλ 보ν μ λ°©μμ λλ€. μ¬κ·ν¨μλ₯Ό μ΄μ©ν΄ ꡬνν κ²½μ° κ°μ΄ λ무 컀μ ν¨μ νΈμΆμ μμ£Ό λ§μ΄ ν΄μΌν κ²½μ° μ€ν μ€λ²νλ‘μ°κ° λ°μν μλ μκ³ , 미리 cache λ°°μ΄μ ν¬κΈ°λ₯Ό μ ν΄μ μ΄κΈ°νν΄λμ΄μΌ νλ€λ λ¨μ λ μκΈ° λλ¬Έμ κ°λ₯νλ€λ©΄ 보ν μ λ°©μμ κΆμ₯νλ€κ³ ν©λλ€!
λμ κ³νλ²μ μ¬μ€ κ°λ μ ν¬κ² μ΄λ ΅μ§ μμ§λ§ μ μ©νκΈ°κ° μ½μ§ μμ κ² κ°μ΅λλ€..(λμ κ³νλ²μΌλ‘ ν μ μκ² κ΅¬λλ₯Ό κΉ¨λ«κ³ μ νμμ μΈμ°λ κ³Όμ μ΄ μ΄λ €μ΄ κ² κ°μμ..) κ·Έλ κΈ° λλ¬Έμ λ§μ½ νΉμ ν λ¬Έμ λ₯Ό μμ νμ μκ³ λ¦¬μ¦μΌλ‘ μ κ·Όνμ λ μκ°μ΄ λ§€μ° μ€λκ±Έλ¦°λ€λ©΄ λμ κ³νλ²μ μ μ©ν μ μλμ§ ν΄κ²°νκ³ μ νλ λΆλΆ λ¬Έμ λ€μ μ€λ³΅ μ¬λΆλ₯Ό νμΈνλ λ°©μμΌλ‘ μ κ·Όνλ κ²λ μ’μ λ°©λ²μΈ κ² κ°μ΅λλ€!
[μ°Έκ³ μλ£]
<μ΄κ²μ΄ μ½λ© ν μ€νΈλ€ with νμ΄μ¬>