κΉ¨μ•Œ κ°œλ… πŸ“‘/μ•Œκ³ λ¦¬μ¦˜

동적 ν”„λ‘œκ·Έλž˜λ° (Dynamic Programming), 상ν–₯식(Bottom-up) 및 ν•˜ν–₯식(Top-down) μ ‘κ·Ό

interfacer_han 2024. 1. 4. 14:00

#1 μ•Œκ³ λ¦¬μ¦˜

#1-1 μ •μ˜

동적 ν”„λ‘œκ·Έλž˜λ°μ„ ν•œ 쀄 μš”μ•½ν•˜λ©΄ μ€‘λ³΅μ˜ μ œκ±°λ‹€. 정적(static)μ΄λΌλŠ” κ°œλ…κ³Ό λ°˜λŒ€λ˜λŠ” κ°œλ…μœΌλ‘œμ„œ, 동적(dynamic)μ΄λΌλŠ” 단어가 이름에 λΆ™μ—ˆλ‹€. ν™•μ‹€νžˆ static이 뢙을 λ§Œν•œ μž‘μ—…μ€ μ•„λ‹ˆμ§€λ§Œ, κ·Έλ ‡λ‹€κ³  λ§Žμ€ 단어듀 쀑에 ꡳ이 dynamicκ°€ 뢙을 ν•„μš” λ˜ν•œ μ—†λ‹€. '동적', ' dynamic'μ΄λΌλŠ” 이름은 동적 ν”„λ‘œκ·Έλž˜λ°μ˜ (μ€‘λ³΅μ˜ μ œκ±°λΌλŠ”) 핡심을 μ§κ΄€μ μœΌλ‘œ μ΄ν•΄ν•˜μ§€ λͺ»ν•˜κ²Œ λ§Œλ“ λ‹€. ν•˜μ§€λ§Œ, κ΄€λ‘€μ μœΌλ‘œ 이미 ꡳ어진 이름이라 μ•žμœΌλ‘œλ„ 쓰일 κ²ƒμ΄λΌλŠ” 사싀은 μ•ˆνƒ€κΉŒμš°λ©΄μ„œλ„ λΆ„λͺ…ν•˜λ‹€.
 

#1-2 μ’…λ₯˜

동적 ν”„λ‘œκ·Έλž˜λ°μ€ 이와 같이 2가지 λ°©μ‹μœΌλ‘œ λ‚˜λ‰œλ‹€.
 

#1-3 상ν–₯식(Bottom-up) μ ‘κ·Ό

 

[λ°±μ€€] 17626 - Four Squares

#1 μ•Œκ³ λ¦¬μ¦˜ 123 123 μž¬κ·€ ν•¨μˆ˜κ°€ ν‰κ· μ μœΌλ‘œ 1만 번 언저리 ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ 즈음 μŠ€νƒμ˜€λ²„ν”Œλ‘œμš°κ°€ κ±Έλ Έλ‹€. #2 μ—¬λ‹΄ dpλ¬Έμ œμΈμ€„ λͺ¨λ₯΄κ³  ν•˜λ£¨ 쒅일을 λ‚ λ Έλ‹€. 그리고 dp문제 νŠΉμ§•μ΄ 죄닀 μΊμ‹±μš© λ³€μˆ˜

kenel.tistory.com

상ν–₯식 동적 ν”„λ‘œκ·Έλž˜λ°μ˜ ν’€μ΄μ˜ μ˜ˆλŠ” μœ„ κ²Œμ‹œκΈ€μ— μžˆλ‹€. ν•΄λ‹Ή κ²Œμ‹œκΈ€μ˜ #1-4κ³Ό #3을 보면 λœλ‹€. μ½”λ“œλ₯Ό 보면, 상ν–₯식 접근을 'λΉˆν‹ˆμ—†μ΄ μŒ“μ•„κ°€λŠ” 방식'이라고 ν•œ 이유λ₯Ό μ•Œ 수 μžˆλ‹€. ν•΄λ‹Ή κ²Œμ‹œκΈ€μ˜ λ°°μ—΄ dpλŠ” 인덱슀 0을 μ œμ™Έν•˜κ³€ μ „λΆ€ λ‹€ μ΄ˆκΉƒκ°’μ΄ μ•„λ‹Œ 값이 ν• λ‹Ήλ˜μ–΄ μžˆλ‹€. ν‹ˆμ΄ μ—†λ‹€. μ•žμœΌλ‘œ μ§€κΈˆλ³΄λ‹€ 더 큰 문제λ₯Ό ν‘ΈλŠ” 데에 μžˆμ–΄, μ–΄λ–€ μž‘μ€ λ¬Έμ œκ°€ 쓰일 지 아닐 μ§€λŠ” μš°λ¦¬κ°€ 폰 λ…Έμ΄λ§Œμ΄ μ•„λ‹Œ 이상 λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€. λ”°λΌμ„œ λΉˆν‹ˆμ—†μ΄ λͺ¨λ“  문제의 ν•΄λ₯Ό κ΅¬ν•΄λ‘λŠ” 것이닀. μ—¬κΈ°μ—μ„œ 상ν–₯식 μ ‘κ·Όμ˜ 단점을 μ•Œ 수 μžˆλ‹€. λ°”λ‘œ λ©”λͺ¨λ¦¬λ₯Ό 많이 μ°¨μ§€ν•œλ‹€λŠ” 점이닀.

μ—¬λ‹΄μœΌλ‘œ, ν•΄λ‹Ή κ²Œμ‹œκΈ€μ˜ #4λ₯Ό 보면 ν•˜ν–₯식 동적 ν”„λ‘œκ·Έλž˜λ°μ˜ 단점도 μ•Œ 수 μžˆλ‹€. μž¬κ·€ν˜ΈμΆœμ΄ κ³Όλ„ν•˜κ²Œ λ§Žμ•„μ§€λ©΄ μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš° λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. λ”°λΌμ„œ κ³Όλ„ν•˜κ²Œ λ§Žμ€ μž¬κ·€ν˜ΈμΆœμ΄ λ°œμƒν•˜λŠ” 문제라면 ν•˜ν–₯식 동적 ν”„λ‘œκ·Έλž˜λ°μ€ μ“°κΈ° μ–΄λ ΅λ‹€.
 

#1-4 ν•˜ν–₯식(Top-down) μ ‘κ·Ό

 

[λ°±μ€€] 1003 - ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜

#1 μ•Œκ³ λ¦¬μ¦˜ #2 μ½”λ“œ (μžλ°”) import java.util.*; public class Main { public static Map map = new HashMap(); public static void main(String[] args) { Integer[] seedData0 = {1, 0}; Integer[] seedData1 = {0, 1}; map.put(0, seedData0); map.put(1, seedDat

kenel.tistory.com

μ΄λ²ˆμ—λŠ” ν•˜ν–₯식 동적 ν”„λ‘œκ·Έλž˜λ°μ˜ μ˜ˆλ‹€. ν•΄λ‹Ή κ²Œμ‹œκΈ€μ˜ fibonacci()λŠ” 큰 문제λ₯Ό μž‘μ€ 문제둜 μͺΌκ°œλ‚˜κ°„λ‹€. μ΄λ•Œ, ν•œ 번 값이 ꡬ해진 λ¬Έμ œλŠ” Map 객체에 말 κ·ΈλŒ€λ‘œ 'λ©”λͺ¨'λ˜μ–΄, λ‹€μŒμ— 같은 문제λ₯Ό λ§Œλ‚˜λ©΄ λ‹€μ‹œ 계산할 ν•„μš”μ—†μ΄ λ©”λͺ¨ν–ˆλ˜ κ±Έ κ·ΈλŒ€λ‘œ κ°€μ Έλ‹€κ°€ μ“΄λ‹€. 큰 문제λ₯Ό μͺΌκ°œμ–΄ λ‚˜μ˜¨ μ–΄λ–€ μž‘μ€ λ¬Έμ œλŠ” λ°˜λ“œμ‹œ κ·Έ ν•΄λ₯Ό ꡬ해야 ν•˜λŠ” ν•„μˆ˜ λͺ©ν‘œκ°€ 되며, ν•΄λ₯Ό κ΅¬ν•œ 김에 λ©”λͺ¨κΉŒμ§€ ν•˜μ—¬ λ―Έλž˜μ— ν˜Ήμ‹œλΌλ„ λ‚˜μ˜¬ 같은 λ¬Έμ œμ— λŒ€λΉ„ν•˜λŠ” 것이닀.

#1-5 두 μ ‘κ·Όλ²•μ˜ 비ꡐ

상ν–₯식 μ ‘κ·Όκ³ΌλŠ” 달리, ν•˜ν–₯식 μ ‘κ·Όμ˜ μ½”λ“œμ—μ„  μ–΄λ–€ μž‘μ€ 문제의 ν•΄κ°€ 'λ©”λͺ¨'λ˜μ—ˆλŠ”μ§€ μ²΄ν¬ν•˜λŠ” 뢀뢄이 μžˆλ‹€. 상ν–₯식 μ ‘κ·Όμ—μ„œλŠ” μž‘μ€ 문제λ₯Ό 단 ν•˜λ‚˜λ„ λΉ λœ¨λ¦¬μ§€ μ•Šκ³  마치 κΉœμ§€ν•˜λ“― ν’€μ–΄κ°€λ©° μœ„λ‘œ μ˜¬λΌκ°€κΈ° λ•Œλ¬Έμ—, μž‘μ€ 문제λ₯Ό 이전에 이미 ν’€μ–΄μ„œ κ·Έ ν•΄λ₯Ό μ œλŒ€λ‘œ μ €μž₯ν•΄λ†“μ•˜μŒμ„ μ˜μ‹¬ν•  ν•„μš”κ°€ μ—†λ‹€. 반면, 상ν–₯식 μ ‘κ·Όμ—μ„œλŠ” μž‘μ€ ν•΄λ₯Ό λ„엄띄엄 λ©”λͺ¨ν•˜κΈ° λ•Œλ¬Έμ—, μ–΄λ–€ μž‘μ€ λ¬Έμ œκ°€ 이전에 ν’€μ—ˆλ˜ 것인지 ν™•μ‹€μΉ˜ μ•Šλ‹€. λ”°λΌμ„œ, μ²΄ν¬ν•œλ‹€.

동적 ν”„λ‘œκ·Έλž˜λ°μ˜ 두 μ’…λ₯˜ λͺ¨λ‘ 큰 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ μž‘μ€ λ¬Έμ œλ“€μ˜ ν•΄λ₯Ό λ”°λ‘œ μ €μž₯ν•΄λ‘”λ‹€λŠ” 점은 λ™μΌν•˜λ‹€. λ‹€λ§Œ κ·Έ μ €μž₯의 양상이 λ‹€λ₯Ό 뿐이닀. 상ν–₯식 접근이 'λΉˆν‹ˆμ—†μ΄ μŒ“μ•„κ°„λ‹€'라면, ν•˜ν–₯식 접근은 이λ₯Έλ°” 'λΉˆν‹ˆμžˆκ²Œ μŒ“μ•„κ°„λ‹€'κ³  말할 수 μžˆλ‹€. 또, ν•˜ν–₯식 접근이 λ©”λͺ¨λΌλ©΄, 상ν–₯식 접근은 κΉœμ§€λ‹€. 그리고 ν•˜ν–₯식 μ ‘κ·Όμ—μ„œμ˜ λ©”λͺ¨λ₯Ό νŠΉλ³„νžˆ, 캐싱 λ˜λŠ” λ©”λͺ¨μ΄μ œμ΄μ…˜μ΄λΌκ³  λΆ€λ₯Έλ‹€ (상ν–₯식 μ ‘κ·Όμ—μ„œμ˜ λ©”λͺ¨(κΉœμ§€)도 λ§ˆμ°¬κ°€μ§€λ‘œ 캐싱이라고 λΆ€λ₯΄λŠ” κ²ƒμœΌλ‘œ 보인닀. μ—„λ°€νžˆ κ΅¬λΆ„λ˜μ§€λŠ” μ•Šλ‚˜λ³΄λ‹€).

 

#1-6 캐싱

λ©”λͺ¨μ΄μ œμ΄μ…˜(Memoization, λ©”λͺ¨)은 λ©”λͺ¨λ¦¬μ œμ΄μ…˜(Memorization, κΈ°μ–΅)κ³Ό λ‹€λ₯Έ λ‹¨μ–΄λ‹€. λ©”λͺ¨μ΄μ œμ΄μ…˜μ€ λ©”λͺ¨(Memo)μ—μ„œ νŒŒμƒλœ λ‹¨μ–΄λ‹€. λ©”λͺ¨μ΄μ œμ΄μ…˜μ€ μ•½κ°„ ν•™μˆ μ μΈ λŠ¬μ•™μŠ€μ˜ λ‹¨μ–΄λ©°, μ‹€λ¬΄μ—μ„œλŠ” μ£Όλ‘œ μΊμ‹±μ΄λΌλŠ” λ§λ‘œ λΆˆλ¦°λ‹€κ³  ν•œλ‹€. μΊμ‹±μ΄ λ™μ  ν”„λ‘œκ·Έλž˜λ°μ— ν¬ν•¨λ˜λŠ” κ°œλ…μ€ μ•„λ‹ˆλ‹€. μ¦‰, λ™μ  ν”„λ‘œκ·Έλž˜λ°μ˜ λͺ©μ μœΌλ‘œλ§Œ ν•œμ •λ˜μ–΄ μ“°μ΄λŠ” κ°œλ…μ΄ μ•„λ‹ˆλ‹€. 말 κ·ΈλŒ€λ‘œ 'λ©”λͺ¨ν•˜κΈ°'인데 μ–Όλ§ˆλ‚˜ 좔상적이며, 그렇기에 μ–Όλ§ˆλ‚˜ 큰 ν™œμš© κ°€λŠ₯성을 μ§€λ…”κ² λŠ”κ°€?

 

#2 동적 ν”„λ‘œκ·Έλž˜λ° μ‚¬μš© μ‹œμ˜ λ§ˆμŒκ°€μ§

 

[λ°±μ€€] 11053 (κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄)

#1 μ•Œκ³ λ¦¬μ¦˜ Longest increasing subsequence - WikipediaFrom Wikipedia, the free encyclopedia Computer science problem In computer science, the longest increasing subsequence problem aims to find a subsequence of a given sequence in which the subsequenc

kenel.tistory.com

동적 ν”„λ‘œκ·Έλž˜λ°μ€ 도ꡬ일 뿐이닀. κ²°κ΅­ μ‚¬μš©μžλŠ” μ‚¬λžŒμ΄λ‹€.

 

#3 μš”μ•½

동적 ν”„λ‘œκ·Έλž˜λ°μ€ 쀑볡 μ œκ±°λ‹€.
 

#4 이 κ°œλ…μ΄ μ‚¬μš©λœ κΈ€

#4-1 상ν–₯식(Bottom-up) μ ‘κ·Ό

 

[λ°±μ€€] 17626 - Four Squares

#1 μ•Œκ³ λ¦¬μ¦˜ 123 123 μž¬κ·€ ν•¨μˆ˜κ°€ ν‰κ· μ μœΌλ‘œ 1만 번 언저리 ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ 즈음 μŠ€νƒμ˜€λ²„ν”Œλ‘œμš°κ°€ κ±Έλ Έλ‹€. #2 μ—¬λ‹΄ dpλ¬Έμ œμΈμ€„ λͺ¨λ₯΄κ³  ν•˜λ£¨ 쒅일을 λ‚ λ Έλ‹€. 그리고 dp문제 νŠΉμ§•μ΄ 죄닀 μΊμ‹±μš© λ³€μˆ˜

kenel.tistory.com

 

[λ°±μ€€] 9095 - 1, 2, 3 λ”ν•˜κΈ°

#1 μ•Œκ³ λ¦¬μ¦˜ #1-1 동적 ν”„λ‘œκ·Έλž˜λ° (Dynamic Programming), 상ν–₯식(Bottom-up) 및 ν•˜ν–₯식(Top-down) μ ‘κ·Ό #1 μ•Œκ³ λ¦¬μ¦˜ 동적 ν”„λ‘œκ·Έλž˜λ°μ„ ν•œ 쀄 μš”μ•½ν•˜λ©΄ μ€‘λ³΅μ˜ μ œκ±°λ‹€. 정적(static)μ΄λΌλŠ” κ°œλ…κ³Ό λ°˜λŒ€λ˜λŠ” κ°œλ…

kenel.tistory.com

 

[λ°±μ€€] 1676 (νŒ©ν† λ¦¬μ–Ό 0의 개수)

#1 μ•Œκ³ λ¦¬μ¦˜ #1-1 문제의 핡심 이 문제의 핡심은, x!κ°€ 가지고 μžˆλŠ” 2*5 쌍의 갯수만큼 뒀에 0이 λΆ™λŠ”λ‹€λŠ” κ·œμΉ™μ˜ νŒŒμ•…μ΄λ‹€. #1-2 상ν–₯식 동적 ν”„λ‘œκ·Έλž˜λ° 동적 ν”„λ‘œκ·Έλž˜λ° (Dynamic Programming), 상ν–₯식(Bot

kenel.tistory.com

 

#4-2 ν•˜ν–₯식(Top-down) μ ‘κ·Ό

 

[λ°±μ€€] 1003 - ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜

#1 μ•Œκ³ λ¦¬μ¦˜ #2 μ½”λ“œ (μžλ°”) import java.util.*; public class Main { public static Map map = new HashMap(); public static void main(String[] args) { Integer[] seedData0 = {1, 0}; Integer[] seedData1 = {0, 1}; map.put(0, seedData0); map.put(1, seedDat

kenel.tistory.com

 

[λ°±μ€€] 1463 (1둜 λ§Œλ“€κΈ°)

#1 μ•Œκ³ λ¦¬μ¦˜ 동적 ν”„λ‘œκ·Έλž˜λ° (Dynamic Programming), 상ν–₯식(Bottom-up) 및 ν•˜ν–₯식(Top-down) μ ‘κ·Ό #1 μ•Œκ³ λ¦¬μ¦˜ #1-1 μ •μ˜ 동적 ν”„λ‘œκ·Έλž˜λ°μ„ ν•œ 쀄 μš”μ•½ν•˜λ©΄ μ€‘λ³΅μ˜ μ œκ±°λ‹€. 정적(static)μ΄λΌλŠ” κ°œλ…κ³Ό λ°˜λŒ€λ˜λŠ”

kenel.tistory.com