[μκ³ λ¦¬μ¦] λμ κ³νλ²(Dynamic Programming, DP) μμ보기 ( λ°±μ€ 24416λ² νΌλ³΄λμΉ μ-1 with μλ° )
π€ λμ κ³νλ² DP?
볡μ‘ν λ¬Έμ λ₯Ό λ μμ νμ λ¬Έμ λ‘ λλμ΄ ν΄κ²°νλ μκ³ λ¦¬μ¦ μ€κ³ κΈ°λ²μ λλ€.
μ¦, λ¬Έμ ν΄κ²°μ μν΄ μ€κ³νλ λ°©λ²μ΄λ μ κ·Ό λ°©μμ λ§ν©λλ€.
π‘ λ©λͺ¨μ΄μ μ΄μ (Memoization)
λμΌν κ³μ°μ λ°λ³΅ν΄μΌ ν λ, μ΄μ μ κ³μ°ν κ°μ λ©λͺ¨λ¦¬μ μ μ₯ν¨μΌλ‘μ¨ λμΌν κ³μ°μ λ°λ³΅ μνμ μ κ±°νμ¬ νλ‘κ·Έλ¨ μ€ν μλλ₯Ό λΉ λ₯΄κ² νλ κΈ°μ μ΄λ€. λμ κ³νλ²μ ν΅μ¬μ΄ λλ κΈ°μ μ΄λ€.
wikipedia
λμ κ³νλ²(DP)μ ν΅μ¬μ΄ λλ κΈ°μ λ‘ κ°μ₯ ν° νΉμ§μ΄λΌκ³ ν μ μμ΅λλ€.
μν₯μ, νν₯μ μ κ·Ό λ°©μμ ν΅ν΄ λ¬Έμ λ₯Ό μμ νμ λ¬Έμ λ‘ λλμ΄ μ΄λ₯Ό ν΄κ²°νλ©΄μ νμ λ¬Έμ μ κ²°κ³Όλ₯Ό λ©λͺ¨μ΄μ μ΄μ μ¦ λ©λͺ¨λ¦¬μ μ μ₯ν¨μΌλ‘μ¨ μ€λ³΅ μ°μ°μ μ€μΌ μ μμ΅λλ€.
π μν₯μ(bottom-up) μ κ·Ό
μμ νμ λ¬Έμ λ€λΆν° μμνμ¬ κ·Έ κ²°κ³Όλ₯Ό μ μ₯νκ³ , μ΄λ₯Ό μ΄μ©νμ¬ μ μ§μ μΌλ‘ ν° λ¬Έμ μ λ΅μ ꡬν΄λκ°λ μ κ·Ό λ°©μμ λλ€.
π νν₯μ(top-down) μ κ·Ό
μ¬κ· νΈμΆμ μ΄μ©νμ¬ λ¬Έμ λ₯Ό ν΄κ²°ν λ μ£Όλ‘ μ°μ λλ€.
μ¦, ν° λ¬Έμ λ₯Ό μμ νμ λ¬Έμ λ‘ λλμ΄ ν΄κ²°νλ μ κ·Ό λ°©μμ λλ€.
β λμ κ³νλ²(DP) μ μ© μ‘°κ±΄
π μ€λ³΅λλ λΆλΆ λ¬Έμ (Overlapping Subproblems)
DPλ λ¬Έμ λ₯Ό μμ νμ λ¬Έμ λ‘ λλκ³ , μμ λ¬Έμ μ κ²°κ³Όλ₯Ό μ¬μ¬μ©νμ¬ μνλ κ²°κ³Όλ₯Ό λμΆνλ κ³Όμ μ΄λΌκ³ ν μ μμ΅λλ€.
λ°λΌμ μμ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ λμΌν μμ λΆλΆ λ¬Έμ κ° λ°λ³΅μ μΌλ‘ λ°μνλ κ²½μ° DPλ₯Ό μ μ©ν μ μμ΅λλ€.
π μ΅μ λΆλΆ ꡬ쑰 (Optimal Substructure)
μ£Όμ΄μ§ λ¬Έμ μ μ΅μ μ λ΅μ΄ νμ λ¬Έμ μ μ΅μ μ λ΅μ ν΅ν΄ μ»μ΄μ§ μ μλ κ²½μ°λ₯Ό λ§ν©λλ€.
π Example
public static int fibonacci(int n ){
if( n == 1 || n == 2){
return 1;
}
return fibonacci(n-1) + fibonacci(n - 2);
}
μ μ½λλ νΌλ³΄λμΉ μλ₯Ό μ¬κ· νΈμΆμ ν΅ν΄ ꡬνν΄ λ³΄μμ΅λλ€.
νΌλ³΄λμΉ μμ΄μ μ΄μ λ μ«μμ ν©μ λ€μ μ«μλ‘ λνλ΄λ μμ΄μ λλ€.
λ€μ μ«μλ₯Ό μμλ΄λ €λ©΄ μ΄μ μ«μλ€μ ν©μ μμμΌ ν©λλ€ μ΄ κ³Όμ μμ κ·Έλ¦Όμ²λΌ μ€λ³΅λλ μ°μ° μ¦, μ€λ³΅λλ λΆλΆ λ¬Έμ κ° λ°μνλ€λ κ±Έ μ μ μμ΅λλ€.
λν μ 체 λ¬Έμ (fibonacci(5))μ λ΅μ λΆλΆ λ¬Έμ λ€μ λ΅μ ν΅ν΄ μ»μ΄μ§ μ μκΈ° λλ¬Έμ μ΅μ λΆλΆ ꡬ쑰λΌκ³ ν μ μμ΅λλ€.
λ 쑰건μ λ§μ‘±ν¨μΌλ‘ νΌλ³΄λμΉ μλ₯Ό ꡬνκΈ° μν΄μ DPλ°©λ²λ‘ μ μ μ©ν΄ λ³Ό .
β DP λ¬Έμ
λμ΄λ : λΈλ‘ μ¦ 1 π₯
λ°±μ€ 24416λ² νΌλ³΄λμΉ μ 1
24416λ²: μκ³ λ¦¬μ¦ μμ - νΌλ³΄λμΉ μ 1
μ€λλ μμ€μ΄λ λμ νλ‘κ·Έλλ° μμ μ‘°κ΅λ₯Ό νκ³ μλ€. μλΉ κ° μμ ν λ΄μ©μ νμλ€μ΄ μ μ΄ν΄νλμ§ λ¬Έμ λ₯Ό ν΅ν΄μ νμΈν΄λ³΄μ. μ€λμ nμ νΌλ³΄λμΉ μλ₯Ό μ¬κ·νΈμΆκ³Ό λμ νλ‘κ·Έλλ°
www.acmicpc.net
nμ νΌλ³΄λμΉ μλ₯Ό μ¬κ· νΈμΆκ³Ό DPλ₯Ό ν΅ν΄ ꡬνλ μκ³ λ¦¬μ¦μ λΉκ΅νκΈ° μν΄ κ° μ½λκ° λͺ λ² νΈμΆλλμ§ νΈμΆ νμλ₯Ό μΆλ ₯νλ λ¬Έμ μ λλ€.
DPλ°©λ²λ‘ μ μ μ©ν μ½λμ λλ€.
bottom-up μ κ·Όμ ν΅ν΄ μμ λ¬Έμ μ¦, νΌλ³΄λμΉ μμ 첫λ²μ§Έ μ, λ λ²μ§Έ μ μ°μ°μ μμμΌλ‘ κ²°κ΄κ°μ μ μ₯νλ©΄μ μ μ₯ν κ²°κ΄κ°μ ν΅ν΄ μ€λ³΅ μ°μ°μ μ€μ΄κ³ μ μ°¨ nλ²μ§Έ μκΉμ§ κ°μ λμΆν΄ λ΄λ κ³Όμ μΌλ‘ μ§νν©λλ€.
DPμ ν΅μ¬μΈ λ©λͺ¨μ΄μ μ΄μ μ ν΅ν΄μ μ΄μ κ°λ€μ μ μ₯νμ¬ μ€λ³΅ μ°μ°μ μ κ±°νκΈ° μν΄ λ°°μ΄ fibArrμ μ¬μ©ν©λλ€.
static void fibonacci(int n ){
// νΌλ³΄λμΉ μμ 첫λ²μ§Έμ λλ²μ§Έλ 1μ΄κΈ° λλ¬Έμ 1λ‘ μ€μ ν΄ μ€λλ€.
fibArr[0] = 1;
fibArr[1] = 1;
for( int i = 2; i<n; i++){
fibArr[i] = fibArr[i-1] + fibArr[i-2];
cnt++;
}
}
π
λ¬Έμ μμλ νΈμΆ νμλ₯Ό λ¬»κ³ μκΈ° λλ¬Έμ cntλ₯Ό μΆλ ₯νμ§λ§ nλ²μ§Έμ νΌλ³΄λμΉ μλ₯Ό μΆλ ₯ν΄μΌ νλ€λ©΄ fibArr[n-1]μ ν΅ν΄ μ»μ μ μμ΅λλ€. ( n=5 μΌ λ fibArr = { 1, 1, 2, 3, 5 } )
λν λ¬Έμ μ λ²μκ° n(5<= n <= 40)μ΄κΈ° λλ¬Έμ μκ΄μμ§λ§ λ§μ½ λ²μκ° 1λΆν° μμμ΄λΌλ©΄ ArrayIndexOutOfBoundsExceptionμ΄ λ°μν μ μκΈ° λλ¬Έμ μ΅λ λ²μλ‘ λ©λͺ¨μ΄μ μ΄μ ν λ°°μ΄μ μ μΈν΄μ£Όλ©΄ ν΄κ²°ν μ μμ΅λλ€. ( fibArr = new int[μ΅λλ²μ] )
π μ 체 μ½λ
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.StringBuilder;
public class Main{
static int n, cnt;
static int[] fibArr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
n = Integer.parseInt(br.readLine());
fibArr = new int[n];
cnt = 0;
fib(n);
sb.append(cnt).append(" ");
cnt = 0;
fibonacci(n);
sb.append(cnt);
System.out.print(sb);
br.close();
}
static int fib(int n){
if( n == 1 || n == 2){
cnt++;
return 1;
} else {
return fib(n -1) + fib(n - 2);
}
}
static void fibonacci(int n ){
fibArr[0] = 1;
fibArr[1] = 1;
for( int i = 2; i<n; i++){
fibArr[i] = fibArr[i-1] + fibArr[i-2];
cnt++;
}
}
}
π Reference : https://velog.io/@boyeon_jeong/%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming