CHAPTER 04 ๋ค์ด๋ด๋ฏน ํ๋ก๊ทธ๋๋ฐ ์ ์ฉ ์ ๋ต
- ์ฌ๊ท ํธ์ถ์ ์ฌ์ฉํด ํ์ด๋ฒ ์์ฑํ๊ธฐ
- ๋ฌธ์ ์ ๋์ด๋์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ DP๋ ๋ฉ๋ชจ์ด์ ์ด์ ์ฌ์ฉํ์ฌ ํ์ด๋ฒ ๊ฐ์ ํ๊ธฐ
4.1 ์ธ ๋ฐฉ๋ฒ์ ์ฐจ๋ก๋๋ก ์ ์ฉํ๋ฉฐ ๋ฌธ์ ํ๊ธฐ
ํ๋ ฌ์์ ์ต์ ์ด๋ ๋น์ฉ ๊ตฌํ๊ธฐ
๋น์ฉ ํ๋ ฌ์ด ์ฃผ์ด์ก์ ๋ ํ๋ ฌ์ ๊ฐ์ฅ ์ข์๋จ ์ ์์ ๊ฐ์ฅ ์ฐํ๋จ ์ ๋ก ์ด๋ํ๋ ๋ฐ ๋๋ ์ต์ ๋น์ฉ์ ๋ฐํํ๋ ํจ์๋ฅผ ์์ฑํด๋ณด์.
- ๋จ ์๋์ชฝ๊ณผ ์ค๋ฅธ์ชฝ์ผ๋ก ํ ์นธ์ฉ๋ง ์ด๋ํ ์ ์๋ค๊ณ ๊ฐ์ ํ๋ค.
1. ์ฌ๊ท ํธ์ถ
์ฌ๊ท ํธ์ถ๋ก ๋ฌธ์ ๋ฅผ ํ ๋๋ ํฐ ๋ฌธ์ ๋ฅผ ์์ ํ์ ๋ฌธ์ ๋ฅผ ์ฌ์ฉํด ์ ์ํ ํ, ์ฌ๊ทํธ์ถ์ ํตํด ํ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
def minPathCose(cost, m, n) :
x = minPathCost(cost, m-1, n)
y = minPathCost(cost, m, n-1)
return getMin(x, y) + cost[m][n];
์ ์ฝ๋์์ ์ข ๋ฃ ์กฐ๊ฑด์ ์๊ฐํด๋ณด์.
m
๊ณผn
๋ชจ๋ 0์ธ ๊ฒฝ์ฐ : ์ถ๋ฐ์ง๊ฐ ๋ชฉ์ ์ง์ธ ๊ฒฝ์ฐ -> cost[0][0] ๋ฆฌํดm
== 0 &&n
!= 0 : ์ค๋ฅธ์ชฝ์ผ๋ก๋ง ์ด๋ํ๋ ๊ฒฝ์ฐ, ๋ฐ๋ก ์ผ์ชฝ ์ ์ ์ต์ ์ด๋ ๋น์ฉ + ํ์ ์ ์ ๋น์ฉm
!= 0 &&n
== 0 : ์๋๋ก๋ง ์ด๋ํ๋ ๊ฒฝ์ฐ, ๋ฐ ์ ์ ์ ์ต์ ์ด๋ ๋น์ฉ + ํ์ฌ ์ ์ ๋น์ฉ
์ด ๊ฒฝ์ฐ์์ 1๋ฒ์ ์ข ๋ฃ์กฐ๊ฑด์ด์ง๋ง 2, 3๋ฒ์ ํน์ ํ ์กฐ๊ฑด์ผ ๋ฟ์ด๊ณ ์ข ๋ฃ ์กฐ๊ฑด์ ์๋๋ค. ์ข ๋ฃ ์กฐ๊ฑด์ ๋ฐ์ํ์ฌ ์ฝ๋๋ฅผ ๋ค์ ์์ฑํด๋ณด์.
def getMin(a, b) :
return a if a < b else b
def minPathCost(cost, m, n) :
if m == 0 && n == 0 : return cost[0][0]
if m == 0 : return minPathCost(cost, 0, n-1) + cost[0][n]
if n == 0 : return minPathCost(cost, m-1, 0) + cost[m][0]
x = minPathCost(cost, m-1, n)
y = minPathCost(cost, m, n-1)
return getMin(x, y) + cost[m][n];
- ๋ฌธ์ ์ : ๋์ผํ ๊ณ์ฐ์ ์ค๋ณต์ ์ผ๋ก ํ๊ฒ ๋๋ค. ์ฌ๊ทํธ์ถ์ด๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ๋ ๋ง์ด ์ฌ์ฉํ๋ค.
2. ๋ฉ๋ชจ ์ ๋ต
ํ๋ฒ ํธ์ถํ ์ธ์์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ๋ฉ๋ชจ์ ๋ต์ ์ฌ์ฉํ์!
def getMin(a, b) :
return a if a < b else b
def minPathCost(cost, m, n) :
# ์ด๋ฏธ ์บ์ฑ
if MEM[m][n] != 0 : return MEM[m][n]
if m == 0 && n == 0 : return cost[0][0]
elif m == 0 : return minPathCost(cost, 0, n-1) + cost[0][n]
elif n == 0 : return minPathCost(cost, m-1, 0) + cost[m][0]
else :
x = minPathCost(cost, m-1, n)
y = minPathCost(cost, m, n-1)
MEM[m][n] = getMin(x, y) + cost[m][n]
return MEM[m][n]
- ์ฌ๊ท ํธ์ถ์ ์กด์ฌํ์ง๋ง ํ๋ฒ ๊ณ์ฐํ ํ์ ๋ฌธ์ ๋ ๋ค์ ๊ณ์ฐํ์ง ์๋๋ค.
3. ์ํฅ์ ๋ค์ด๋ด๋ฏน ํ๋ก๊ทธ๋๋ฐ
def getMin(a, b) :
return a if a < b else b
def minPathCost(cost, m, n) :
# ์ด๋ฏธ ์บ์ฑ
MEM[0][0] = cose[0][0]
for j in range (1, N) :
MEM[0][j] = MEM[0][j-1] + cost[0][j]
for i in range (1, N) :
MEM[i][0] = MEM[i-1][0] + cost[i][0]
for i in range(1, M):
for j in range(1, N) :
MEM[i][j] = getMin(MEM[i-1][j], MEM[i][j-1]) + cost[i][j];
return MEM[M-1][N-1];
4.2 ๋ค์ด๋ด๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉํ ๋ฌธ์ ํด๊ฒฐ
DP์ ์ ์ฉ ์ฌ๋ถ๋ฅผ ๊ฐ์ฅ ํ์คํ๊ฒ ํ์ธํ๋ ๋ฐฉ๋ฒ
- ๋ฌธ์ ๊ฐ ์ต์ ์ ํ์๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ?
- ํ์ ๋ฌธ์ ๋ฅผ ๋ฐ๋ณตํด์ ๊ณ์ฐํ๊ณ ์๋๊ฐ?
์ด๋ค ๊ฐ์ ์ต์ ํ, ์ต๋ํ, ์ต์ํํ๊ฑฐ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์ฐพ๋ ๋ฌธ์ ๊ฐ ์ต์ ์ ํ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๊ณ ์์ ๋ ๊ณ ๋ คํด๋ณด์!
DP๋ก ๋ฌธ์ ํ๊ธฐ! ๐งโโ๏ธ
- DP๋ฅผ ์ ์ฉํ ์ ์๋ ๊ฒฝ์ฐ์ธ์ง ํ์ธํ๋ค.
- ์ ํ์ ๋๋ ์ฌ๊ท ๊ณผ์ ์ ์ ์ํ๋ค.
- ๋ฌธ์ ๋ฅผ ํ์ ๋ฌธ์ ๋ฅผ ์ฌ์ฉํ์ฌ ํํฅ์์ผ๋ก ์ ์ : ์๊ฐ๋ณต์ก๋๋ ๊ณ ๋ คํ์ง ์์
- ๊ธฐ๋ณธ ์ผ์ด์ค์ ๋ํ ๋ต์ ์ ์
- ์ข ๋ฃ ์กฐ๊ฑด ์ถ๊ฐ
- (์ ํ์ ) ๋ฉ๋ชจ ์ ๋ต ์๋ : ํ์ ๋ฌธ์ ์ ํด๋ต์ ์บ์ฑํ ํ ๊ฐ์ ๋ฌธ์ ๋ฅผ ํ ๋ ์ ์ฅ๋ ๊ฐ ์ฌ์ฉ
- ์ํฅ์์ผ๋ก ๋ฌธ์ ํ์ด ๋์ : ์ฌ๊ท ํธ์ถ์ ์ ๊ฑฐํ๊ณ ๊ธฐ๋ณธ ์ผ์ด์ค์์ ์ถ๋ฐํ๋ ์งํ ๋ฐฉํฅ์ผ๋ก ์ฌ์ ์, ํ์ํ ๊ฐ๋ค๋ง ์บ์ฑ
์์ : ํ์ผ๋ก ๊ณตํฐ ์ฑ์ฐ๊ธฐ
2 * n ํฌ๊ธฐ์ ๊ณตํฐ๊ฐ ์ฃผ์ด์ก์ ๋ 2 * 1 ํฌ๊ธฐ์ ํ์ผ์ ๊ฐ๋ก ํน์ ์ธ๋ก๋ก ๋ฐฐ์นํ๋ฉฐ ๋ฎ๊ณ ์ ํ ๋์ ๊ฒฝ์ฐ์ ์
์ฌ๊ท ๊ณผ์ ์ ์ ์ํด๋ณด์.
- ์ฒซ ๋ฒ์งธ ํ์ผ์ ์ธ๋ก๋ก ๋ฐฐ์นํ์. ๊ทธ๋ผ ๋ฌธ์ ๋ 2 * (n-1) ํฌ๊ธฐ ๊ณตํฐ์ ํ์ผ์ ๋ฐฐ์นํ๋ ๊ฒฝ์ฐ์ ์๋ก ์ค์ด๋ ๋ค.
- ์ฒซ ๋ฒ์งธ ํ์ผ์ ๊ฐ๋ก๋ก ๋ฐฐ์นํ๋ฉด ๋ ๋ฒ์งธ ํ์ผ๋ ๋ฐ๋์ ๊ฐ๋ก๋ก ๋ฐฐ์นํด์ผ ํ๋ค. ๋ฌธ์ ๋ 2* (n-2) ํฌ๊ธฐ ๊ณตํฐ์ ํ์ผ์ ๋ฐฐ์นํ๋ ๊ฒฝ์ฐ์ ์๋ก ์ค์ด๋ ๋ค.
def countWays(n) :
if n == 1 : return 1
if n == 2 : return 2
return countWays(n-1) + countWays(n-2)
์์ : ํน์ ์ ์์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์
ํ๋ ์ด์ด๊ฐ ํ ๋ฒ์ 3์ ๋๋ 5์ ๋๋ 10์ ์ ์ป์ ์ ์์ ๋ n์ ์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์
์ ํ์
n์ ์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์
= (n-10)์ ์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์ + (n-5)์ ์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์ + (n-3)์ ์ ๋๋ฌํ๋ ๊ฒฝ์ฐ์ ์
์ฌ๊ท๋ก ํธ๋ ์ฝ๋
def waysToScore(n):
if n < 0 : return 0
if n == 0 : return 1
return waysToScore(n-10) + waysToScore(n-5) + waysToScore(n-3)
- ์ญ์๋ ์ค๋ณต์ด ๋ฐ์ํจ! ๋นํจ์จ์ ~
DP๋ก ํ์ด๋ณด์.
def waysToScore(n):
arr = [0] * n
arr[0] = 1
for i in ranger(1, n) :
if i -3 >= 0 : arr[i] += arr[i-3]
if i -5 >= 0 : arr[i] += arr[i-5]
if i -10 >= 0 : arr[i] += arr[i-10]
return arr[n]
์์ : ์ฐ์๋ ๋ถ๋ถ ๋ฐฐ์ด์ ์ต๋๊ฐ ๊ตฌํ๊ธฐ
์ ์๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด์์ ์ฐ์๋ ๋ถ๋ถ ๋ฐฐ์ด์ ํฉ์ ์ต๋๊ฐ์ ๋ฆฌํดํ๋ ํจ์
์์ ํ์์๊ณ ๋ฆฌ์ฆ
def maxSubArraySum(arr, n) :
maxSum = 0
tempSum = 0
for i in range(n):
tempSum = 0
for j in range(i,n):
tempSum += arr[j]
if (tempSum > maxSum) : maxSum = tempSum
return maxSum
- ์ด ๊ฒฝ์ฐ์๋ ๋ฐฐ์ด์ ๋ชจ๋ ์์๊ฐ ์์์ผ ๋๋ ์ค๋ต์ธ 0์ ๋ฆฌํดํ๋ค.
- ์๊ฐ๋ณต์ก๋๊ฐ
O(n^2)
์นด๋ฐ์ธ ์๊ณ ๋ฆฌ์ฆ
def maxSubArraySum(arr, n) :
maxSumSoFar = 0
maxSumEndingHere = 0
for i in range(n):
maxSumEndingHere += arr[i];
if maxSumEndingHere < 0 : maxSumEndingHere = 0
if maxSumEndingHere > maxSumSoFar :
maxSumSoFar = maxSumEndingHere
return maxSumSoFar