15์ฅ. ๋์ ๊ณํ๋ฒ
15-1. ๋์ ๊ณํ๋ฒ(Dynamic Programming) ๊ฐ๋
- ์ ์ฒด ๋ฌธ์ ๋ฅผ ํ ๋ฒ์ ํด๊ฒฐํ๋ ๊ฒ์ด ์๋๋ผ ์์ ๋ถ๋ถ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ๊ณ ์ด๊ฒ๋ค์ ํ์ฉํ์ฌ ์ ์ฒด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
- ๋์ ๊ณํ๋ฒ์ ํจ์จ์ ์ผ๋ก ํ์ฉํ๊ธฐ ์ํด ์ถฉ์กฑ ๋์ด์ผ ํ๋ ์กฐ๊ฑด
- ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋์์ ๋ ๋์ผํ ์์ ๋ฌธ์ ๋ฐ๋ณต ๋ฑ์ฅ
- ํฐ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ
์ ์์ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ
์ ํฉ์ผ๋ก ๊ตฌ์ฑ
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ(opimal substructure)
: ์์ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ
์ ํฉ์ผ๋ก ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๊ตฌ์กฐ
- ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ (overlapping subproblems)
: ํฐ ๋ฌธ์ ๋ฅผ ๋๋์์ ๋ ์์ ๋ฌธ์ ๊ฐ ์ฌ๋ฌ ๊ฐ ๋ฐ๋ณต๋๋ ๋ฌธ์
1) ์ ํ์ ์ธ์ฐ๊ธฐ์ ๋์ ๊ณํ๋ฒ
- ์ ์ฐจ1) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํด๊ฐ ์ด๋ฏธ ์๋ค๊ณ ๊ฐ์ ํ๋ค
- ์ ์ฐจ2) ์ข
๋ฃ ์กฐ๊ฑด์ ์ค์ ํ๋ค
- ์ ์ฐจ3) ์ ์ฐจ 1, 2๋ฅผ ํ์ฉํด ์ ํ์์ ์ธ์ด๋ค
- ์ ํ์ ๊ตฌํ : ์ฌ๊ท ํ์ฉ
- ์ฌ๊ท ํธ์ถ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ : ๋ฐ๋ณต๋ฌธ ๋๋ ๋ฉ๋ชจ์ด์ ์ด์
ํ์ฉ
2) ์ฌ๊ท ํธ์ถ์ ํ์๋ฅผ ์ค์ฌ์ฃผ๋ ๋ฉ๋ชจ์ด์ ์ด์
- ๋ฉ๋ชจ์ด์ ์ด์
: ์ด๋ฏธ ๊ณ์ฐํ ๊ฐ์ ์ ์ฅํด๋์๋ค๊ฐ ์ด ํ ์ธ ์ผ์ด ์์ ๋ ํ์ฉ
- ํผ๋ณด๋์น ์ ๊ตฌํ๊ธฐ ๋ฌธ์ : ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ์ด๋ฉด์ ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ ์ ํด๋น
- ์ ํ์ ๊ตฌํ : ์ฌ๊ท + ๋ฉ๋ชจ์ด์ ์ด์
ํ์ฉ
3) ์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด
- ๋ถ๋ถ ์์ด : ์ฃผ์ด์ง ์ญ๋ ค ์ค ์ผ๋ถ๋ฅผ ๋ฝ์ ์๋ก ๋ง๋ ์์ด(๋จ, ๊ฐ๊ฐ์ ์ด์๋ ์ ํ ๊ด๊ณ ์ ์ง ํ์)
- ์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด(Longest Increasing Subsequence;LIS) : ๋ถ๋ถ ์์ด์ ์์๊ฐ ์ค๋ฆ์ฐจ์์ ์ ์งํ๋ฉด์๋ ๊ธธ์ด๊ฐ ๊ฐ์ฅ ๊ธด ์์ด
- LIS์ ๊ธธ์ด ๋์ ๊ณํ๋ฒ์ผ๋ก ๊ตฌํ๊ธฐ
4) ์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด
- Longest Common Subsequence(LCS)
- ๋ ์์ด์ด ์ด๋ค ๊ธฐ์ค์ ๋ฐ๋ผ ์์ชฝ์์ ๊ณตํต์ผ๋ก ๋ฐ๊ฒฌํ ์ ์๋ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ์์ด
- LCS์ ๊ธธ์ด ๋์ ๊ณํ๋ฒ์ผ๋ก ๊ตฌํ๊ธฐ
15-2. ๋ชธํ๊ธฐ ๋ฌธ์
- ๋ฌธ์ 70_LCS ๊ธธ์ด ๊ณ์ฐํ๊ธฐ
'''
<์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด ๊ตฌํ๊ธฐ>
1. dp 2์ฐจ์ ๋ฐฐ์ด ์ค๋น
2. dp(0, 0) = 0
3. str1[i] == str2[j] >> dp(i, j) = dp(i-1, j-1) + 1
4. str1[i] != str2[j] >> max(dp(i-1, j), dp(i, j-1))
'''
def solution(str1, str2):
n = len(str1)
m = len(str2)
dp = [[0] * (m+1) for _ in range(n+1)]
for i in range(0, n):
for j in range(0, m):
if str1[i] == str2[j]:
dp[i+1][j+1] = dp[i][j] + 1
else:
dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j])
return max(max(dp))
# TEST ์ฝ๋ ์
๋๋ค. ์ฃผ์์ ํ๊ณ ์คํ์์ผ๋ณด์ธ์
print(solution("ABCBDAB","BDCAB")) # ๋ฐํ๊ฐ : 4
print(solution("AGGTAB","GXTXAYB")) # ๋ฐํ๊ฐ : 4
- ๋ฌธ์ 71_LIS ๊ธธ์ด ๊ณ์ฐํ๊ธฐ
'''
<์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด ๊ธธ์ด ๊ตฌํ๊ธฐ>
>> ํด๋น ์ซ์๋ก ๋๋๋ LIS ๊ธธ์ด ๋ฃ๊ธฐ
0. n ๊ธธ์ด์ result ์ด๊ธฐํ(0์ผ๋ก)
1. result[0] = 1
2. ์์ด์ ์์๋๋ก ์ํ
1) ํ์ฌ ๊ฐ ์ด์ ๊ฐ ์ํ
ใฑ) ํ์ฌ ๊ฐ๋ณด๋ค ์์ ๊ฐ๋ค ์ค LIS ๊ธธ์ด ์ต๋์น + 1
'''
def solution(nums):
n = len(nums)
lengths = [1] * n
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j]:
lengths[i] = max(lengths[i], lengths[j] + 1)
return max(lengths)
# TEST ์ฝ๋ ์
๋๋ค. ์ฃผ์์ ํ๊ณ ์คํ์์ผ๋ณด์ธ์
print(solution([1, 4, 2, 3, 1, 5, 7, 3])) # ๋ฐํ๊ฐ : 5
print(solution([3, 2, 1])) # ๋ฐํ๊ฐ : 1
- ๋ฌธ์ 72_์กฐ์ฝ๋ ๋ฌธ์
def solution(arr):
m = len(arr[0])
dp = [[0] * m for _ in range(4)]
dp[0][0] = arr[0][0]
dp[1][0] = arr[1][0]
dp[2][0] = arr[2][0]
dp[3][0] = arr[0][0] + arr[2][0]
for i in range(1, m):
dp[0][i] = arr[0][i] + max(dp[1][i-1], dp[2][i-1])
dp[1][i] = arr[1][i] + max(dp[0][i-1], dp[2][i-1], dp[3][i-1])
dp[2][i] = arr[2][i] + max(dp[0][i-1], dp[1][i-1])
dp[3][i] = arr[0][i] + arr[2][i] + dp[1][i-1]
return max(dp[0][-1], dp[1][-1], dp[2][-1], dp[3][-1])
# TEST ์ฝ๋ ์
๋๋ค. ์ฃผ์์ ํ๊ณ ์คํ์์ผ๋ณด์ธ์
print(solution([[1, 3, 3, 2], [2, 1, 4, 1], [1, 5, 2, 3]])) # ๋ฐํ๊ฐ : 19
print(solution([[1, 7, 13, 2, 6], [2, -4, 2, 5, 4], [5, 3, 5, -3, 1]])) # ๋ฐํ๊ฐ : 32
15-3. ํฉ๊ฒฉ์๊ฐ ๋๋ ๋ชจ์ ํ
์คํธ