
https://leetcode.com/problems/unique-paths/description/
์ด ๋ฌธ์ ๋ ์ด์ ์ ํ์๋, Shortest Path in Binary Matrix์ ๋งค์ฐ ์ ์ฌํ๋ฐ ์ฃผ์ด์ง ๋ฐ์ดํฐ๊ฐ grid๋ผ๋ ๊ฒ๊ณผ ๊ฒฝ๋ก๊ฐ (0,0) -> (m-1,n-1)๋ก ์ ํด์ก๋ค๋ ์ ์ด๋ค.
ํ์ง๋ง, ๋ค๋ฅธ ์ ์ 8-direction์์ ์ค์ง ์ค๋ฅธ์ชฝ๊ณผ ์๋ ๋ฐฉํฅ์ผ๋ก๋ง ์ด๋ํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ๋ํ, 0์ผ๋ก ํ์๋ visited cell๋ก๋ง ๊ฐ์ผ ํ๋ค๋ ์ ์ฝ ์กฐ๊ฑด์ด ์๊ณ length๋ฅผ ๋ฆฌํดํ๋ ๊ฒ์ด ์๋, unique path์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ฆฌํดํ๋ค๋ ์ ์์๋ ์ฐจ์ด๊ฐ ์๋ค.
1 <= m, n <= 100
โฐ๏ธ์๊ฐ๋ณต์ก๋: O(2*10^9)๋ณด๋ค ์์์ผํจ.

์์ ๋ฌธ์ ๋ฅผ ์ดํด๋ณด์. ํ์ฐฝ ์์ ๋ ํ์๋ ์ต๋จ๊ฒฝ๋ก ์ฐพ๊ธฐ ๋ฌธ์ ์ ๊ต์ฅํ ๋น์ทํ์ง ์์๊ฐ? ๊ทธ๋ ๋ค! ์ด ๋ฌธ์ ๋ mississippi์ ๊ฐ์ด ๊ฐ์ ๋ฌธ์๋ฅผ ํฌํจํ ์๋ก ๋๋ ์ 11!/(4!4!2!)์ ๊ฐ์ด ์์์ ํํํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, example 1๋ก ๋ดค์ ๋๋, ->->->->->->โโ์ ๋ฐฉ๋ฒ 1๊ฐ์ง๊ฐ ๋์ค๋๋ฐ, ์ด๋ฅผ ์์์ผ๋ก ํํํ๋ฉด (7-1+3-1)! / (7-1)! * (3-1)! ์ด๋ค.
์ด๋ฅผ ์ผ๋ฐํ ํ๋ฉด, (n+m-2)! / (n-1)! * (m-1)!๊ฐ ๋๋ค.
์ด ์์์ ๊ทธ๋๋ก ๋ฆฌํดํ๋ฉด 1์ ์๊ฐ๋ณต์ก๋๋ฅผ ์ป์ ์ ์๋๋ฐ, factorial์ ์ฌ๊ทํจ์๋ก ์ด๋ฃจ์ด์ ธ ์๋๋ฐ, m๊ณผ n์ ๋ฐ์ดํฐ ๊ฐ๋งํผ ํธ์ถํ๋ฏ๋ก ์ด O(m+n)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค. (์๋ํ๋ฉด ๋๋์
์ฐ์ฐ์ ์์ ์๊ฐ์ผ๋ก ์ทจ๊ธํ๊ธฐ ๋๋ฌธ)
์ด์ , ์์ ์์๊ณผ factorial ์ฌ๊ท ํจ์๋ฅผ ์กฐํฉํด์ ์ฝ๋๋ก ๋ น์ด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์๋ค.
class Solution(object):
def uniquePaths(self, m, n):
def fact(x):
# base condition: 0!=1, 1!=1
if x <= 1:
return 1
return fact(x - 1) * x
return fact(n + m - 2) / (fact(n-1) * fact(m-1))
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์ง ๋ค์ ์ ์ถํ๋ฉด ๋ฐํ์ ํ์๊ถ์ ๊ธฐ๋ก๋ ์ ์๋ค ๐ญ

๋จ์ํ๊ฒ top-down ์ฝ๋ ํ๋ซํผ์ ์์ ์ฝ๋์ ์ ์ฉํด์ ํ์ด๋ณด์๋ค.
class Solution(object):
def uniquePaths(self, m, n):
memo = {}
def dp(i, j):
# base condition
if i <= 1 or j <= 1:
return 1
# x๊ฐ memo์ ์์ผ๋ฉด fact๋ฅผ ํธ์ถ
if (i,j) not in memo:
memo[(i,j)] = fact(n + m - 2) / (fact(n - 1) * fact(m - 1))
# ๊ทธ๋ ์ง ์์ผ๋ฉด memo์ value๋ฅผ ๋ฆฌํด
return memo[(i,j)]
def fact(x):
# base condition: 0!=1, 1!=1
if x <= 1:
return 1
return fact(x - 1) * x
return dp(m,n)
๊ทธ๋ฐ๋ฐ, chatgptํํ ๋ฌผ์ด๋ดค๋๋, ์ด ๋ฐฉ์ ์ญ์ factorial ํจ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ ๊ฒ์ ์ง๋์ง ์๋๋ค๊ณ ํ๋ค. ์๋ํ๋ฉด ์ ์ด์ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ memo์ ์ ์ฅํด์ ์ฌ์ฉํ์ง ์๊ณ , ๋ฐ๋ก fact๋ฅผ ํธ์ถํด์ memo[(i, j)]์ ์ ์ฅํ ๋ค์, ๊ทธ ๊ฐ์ ๋ฆฌํดํ๊ธฐ ๋๋ฌธ์ด๋ค.
๐ก์์ ์ฌํญ: ๋ค๋ฅธ ์ฌ๋์ด ๋์ค์ฝ๋ ์ฑ๋์ ์ฌ๋ฆฐ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ๋๋ฐ, ๊ทธ ๋ถ์ factorial ํจ์ ํธ์ถ์์ ์ค๋ณต๋๋ ์ฐ์ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด์ dp๋ฅผ ๊ตฌํํ์๋ค.
class Solution(object):
def uniquePaths(self, m, n):
memo = {}
def fact(x):
if x <= 1:
return 1
if x not in memo:
memo[x] = fact(x - 1) * x # factorial์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ
return memo[x]
return fact(m + n - 2) / (fact(m - 1) * fact(n - 1))
# fact(m + n - 2) ๋ถ๋ถ๋ง ํธ์ถํ๊ณ , ๋ถ๋ชจ๋ ์บ์ฑํ๋ฏ๋ก ์๊ฐ๋ณต์ก๋๋ O(M+N)
๐ง์ฐธ๊ณ ๋ก, ์ด ์ฝ๋์ ์๊ฐ๋ณต์ก๋๋ O(M+N)์ด๊ธฐ ๋๋ฌธ์ O(M*N)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋ dfs๋ก ๊ตฌํํ ์ฝ๋๋ณด๋ค ๋ ํจ์จ์ ์ด๋ค.
์ญ์ bottom-up ์ฝ๋ ํ ํ๋ฆฟ์ fact ํจ์์ ๊ทธ๋๋ก ์ ์ฉํ๋ฉด ๋๋ค.
class Solution(object):
def uniquePaths(self, m, n):
table = {0: 1, 1: 1}
def fact(x): # 0! or 1! = 1
for i in range(2, x + 1): # ์ฐ๋ฆฌ๊ฐ ์ต์ข
์ ์ผ๋ก ์ํ๋ ๊ฐ์ table[x]๊ธฐ ๋๋ฌธ์ initial step์ 2๋ก ํ๋ 1๋ก ํ๋ ์๊ด ์์
table[i] = table[i - 1] * i
return table[x]
# ํจ์๋ฅผ ๋จผ์ ์ ์ํด์ผ ํจ์๋ฅผ ํธ์ถํ ์ ์์
return fact(m + n - 2) // (fact(m - 1) * fact(n - 1))
๐ง์๋ก ์๊ฒ๋ ์ : python 3๋ถํฐ๋ ๊ฒฐ๊ณผ๊ฐ ํญ์ ์ ์๊ฐ ๋๋๋ก ๋ณด์ฅํ๋ ค๋ฉด ์ ์ ๋๋์ //์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํจ.
๐จโ๐ซ๊ทธ๋์ ํจ๋ฐฐ๋ฅผ ์ธ์ ํ๊ณ , ๊ฐ์๋ฅผ ๋ค์ด์ ์ด๋ป๊ฒ top-down์ ๋ฌธ์ ์ ์ ์ฉํ์๋์ง ํ์ตํ์๋ค.
๊ฐ์ ๋งํฌ: https://www.inflearn.com/course/lecture?courseSlug=%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%85%EB%AC%B8-%ED%8C%8C%EC%9D%B4%EC%8D%AC&unitId=140229
"ํ
์คํธ ์ผ์ด์ค๋ ๋ต์ด 2*10^9์ดํ๊ฐ ๋๋๋ก ์์ฑ๋ฉ๋๋ค" -> ์์ ํ์์ ์ฐ๋ฉด, ์๊ฐ์ด๊ณผ!
"๋๋ฌํ ์ ์๋ ๊ฐ๋ฅํ unique paths์ ์" -> ~๋ฐฉ๋ฒ์ ์๋ dp๋ฅผ ํ์ฉ!
์์ ํ์(DFS): grid๋ ์์์ graph๋ก ์๊ฐ์ด ๊ฐ๋ฅ
ํ์ดํ(์๋, ์ค๋ฅธ์ชฝ)์ ์กฐํฉ;
์ ์ฝ์กฐ๊ฑด์ด 1<= m, n <= 100์ด๋ฏ๋ก, ์ต๋ ์ ๋ ฅ ๋ฐ์ดํฐ๋ก ๊ณ์ฐํ๋ฉด 2*10^58์ด๋ฏ๋ก ์์ ํ์์ ๋ถ๊ฐ๋ฅํ๋ค.
def dfs(r, c):
if r == 2 and c == 6: # ์ข
์ ์ ๋๋ฌํ๋ฉด ์ข
๋ฃ
return 1
unique_paths = 0
# ๊ฒฝ๊ณ๊ฐ ๋ฒ์ ์ด๋ด ์ด๋ ์กฐ๊ฑด
if r + 1 < 3:
unique_paths += dfs(r + 1, c) # ์๋๋ก ์ด๋
if c + 1 < 7:
unique_paths += dfs(r, c + 1) # ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋
return unique_paths
๊ทธ๋ฐ๋ฐ, ์ด์ ์ ํ์ตํ min-cost climbing stairs์ ์์ด๋์ด๋ฅผ ํ์ฉํด์ ์ข ์ ์ ๊ธฐ์ค์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์งค ์๋ ์๋ค.
min-cost climbing stairs ๋ฌธ์ ๋ n๋ฒ์งธ๊น์ง ์ค๋ฅด๋ ๋น์ฉ์ (n-1)๋ฒ์งธ ๋น์ฉ๊ณผ (n-2) ๋น์ฉ์ ํฉ์ณ์ ๊ตฌํ๋ค.
์ด์ ๋ง์ฐฌ๊ฐ์ง๋ก, ์ข
์ ์ n๋ฒ์งธ๋ผ๊ณ ์๊ฐํ๊ณ , ์ด๋ฅผ ์์ ๋ฌธ์ ๋ค๋ก ๋๋์ด์ ์๋์ ํด๋นํ๋ (r-1, c)์ ์ค๋ฅธ์ชฝ์ ํด๋นํ๋ (r, c-1)์ ํฉ์ผ๋ก ํํํ ์ ์๋ค.
์ด ์์ด๋์ด๋ฅผ ์ฝ๋๋ก ์ง๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
def dfs(r, c):
if r == 0 and c == 0: # base condition
return 1 # ์์ ๋ฌธ์ ๊ฐ ์์ ์ ๋๋ฌํ๋ฉด 1์ ๋ฆฌํด
unique_paths = 0
# ๊ฒฝ๊ณ๊ฐ ๋ฒ์ ์ด๋ด ์ด๋ ์กฐ๊ฑด
if r - 1 >= 0:
unique_paths += dfs(r - 1, c)
if c - 1 >= 0:
unique_paths += dfs(r, c - 1)
return unique_paths
โ ๏ธ์ด ์ฝ๋๋ ํผ๋ณด๋์น์ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ ๋ฌธ์ ์ ํด๋นํ๋ ์ฌ๊ท ๋ถ๋ถ์ overlapping subproblem(์ค๋ณต ํ์ ๋ฌธ์ )๊ฐ ์ฌ๋ฌ ๊ฐ ์กด์ฌํ๋ค. ๊ทธ๋ฐ๋ฐ ์ด๊ฒ์ด ๋ถํ์ํ ์ฐ์ฐ์ ํด์ ์๊ฐ๋ณต์ก๋๋ฅผ ๋์ด๋ฏ๋ก, DP๋ฅผ ํ์ฉํด์ ์๊ฐ๋ณต์ก๋๋ฅผ ๋ฎ์ถ ์๊ฐ ์๋ค.
top-down ์ฝ๋ ํ๋ซํผ์ ์์ ์์ด๋์ด์ ์ ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ด ์ง๋ณด์๋ค.
class Solution(object):
def uniquePaths(self, m, n):
memo = {}
def dfs(r, c):
if (r, c) == (0, 0): # base condition
return 1
if (r, c) not in memo:
unique_paths = 0
# ๊ฒฝ๊ณ๊ฐ์ ๋ฐ๋ก ์ค์ ํด์ค์ผํจ(์๊ทธ๋ฌ๋ฉด, ๊ฐ์ฅ์๋ฆฌ์ ์์๋ ํญ์ ๊ฑฐ์ง์ด๋์ NoneType์ ๋ฐํ)
if r - 1 >= 0: # ์์ชฝ ์
์์ ์ค๋ ๊ฒฝ์ฐ
unique_paths += dfs(r - 1, c)
if c - 1 >= 0: # ์ผ์ชฝ ์
์์ ์ค๋ ๊ฒฝ์ฐ
unique_paths += dfs(r, c - 1)
memo[(r, c)] = unique_paths
return memo[(r, c)]
return dfs(m - 1, n - 1)
์๋ฅผ ๋ค์ด, m=3, n=7์ด๋ฉด ๊ฐ๊ฐ 1์ ๋นผ์ผ unique path ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ฏ๋ก dfs ์ธ์์ 1์ ๊ฐ๊ฐ ๋บ๋ค.
๊ทธ๋ฐ๋ฐ, ๋์ ๋๋ฆฌ ๋์ ์ด์ค๋ฆฌ์คํธ ์๋ฃ๊ตฌ์กฐ๋ฅผ ํ์ฉํ์ฌ ์ฝ๋๋ฅผ ์งค ์๋ ์๋ค.

dfs(r-1, c)๋ฅผ ๊ณ์ํด์ ํธ์ถํ๋๋ฐ ๊ฒฝ๊ณ ๋ฒ์๋ฅผ ๋์ด๊ฐ๋ฉด 0์ ๋ฆฌํดํ๋๋ก ํด์ ๊ทธ ๊ฐ์ ๋ํด์ฃผ๊ฒ ํ์๋ค.( dfs(r, c-1)๋ ๋ง์ฐฌ๊ฐ์ง )
์์ ๊ทธ๋ฆผ์ ์์ธํ ์ดํด๋ณด์. ์๋์ ํด๋นํ๋ ์
์ด ๊ฒฝ๊ณ ๋ฒ์๋ฅผ ๋์ด๊ฐ์ ํธ์ถ์ด ์ข
๋ฃ๋๋ฉด, ์ค๋ฅธ์ชฝ ์
์ด ๊ทธ๋ ํธ์ถ๋๊ณ , (0,0)์ ๋๋ฌํ ๋๊น์ง ๊ณ์ ํธ์ถ๋๋ค.
๊ทธ ํ์, ์ฌ๊ท์ ์ฑ์ง ๋๋ฌธ์ ๋ฆฌํดํ ๊ฐ์ ๊ณ์ํด์ ์ด์ ์ ํธ์ถ๋ ํจ์์ ์ ๋ฌํด์ค๋ค.
๋นจ๊ฐ์ ๋๊ทธ๋ผ๋ฏธ ์น r=0์ ํจ์ ํธ์ถ์ด ์ข ๋ฃ๋๋ฉด, ๊ทธ์ ์์ผ r=1์ ํจ์๋ค์ด ์ฌ๊ท์ ์ผ๋ก ํธ์ถ๋๋๋ฐ, ์ด๋ memoization์ผ๋ก ์ด๋ฏธ ๊ฐ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์(์ธ๋ชจ ๋ถ๋ถ) ๋ถํ์ํ๊ฒ ๋ ํธ์ถํ ํ์๊ฐ ์๋ค.
r=1๋ถํฐ๋ ๋ชจ์๋ฆฌ ๋ถ๋ถ๊ณผ ๋ฌ๋ฆฌ, (r, c) = ์๋ + ์ค๋ฅธ์ชฝ์ผ๋ก ๊ณ์ํด์ ๊ฐ์ ๋ํด๊ฐ๋ค.
๐ป์ด์ ์์ ๊ทธ๋ฆผ ๋ถ๋ถ์ ์ฝ๋๋ก ๊ตฌํํด๋ณด์.
class Solution(object):
def uniquePaths(self, m, n): # (m,n)์ row x col
memo = {}
def dfs(r, c): # (r,c)๋ ๋ด๋ถ์ ์ฑ๋ถ
# ๊ฒฝ๊ณ๊ฐ ์ค์ (์๊ทธ๋ฌ๋ฉด stack_over_flow)
if r < 0 or c < 0:
return 0 # ํ์ดํ๊ฐ ์์ผ๋๊น 0 ์ฒ๋ฆฌ
if (r, c) == (0, 0): # ์์์ ์ด๋ฉด
return 1 # 1๊ฐ์ง๋ฅผ ๋ฆฌํด(๊ทธ๋์ผ ๋ํด์ง๋๊น)
if (r, c) not in memo:
memo[(r, c)] = dfs(r - 1, c) + dfs(r, c - 1)
return memo[(r, c)]
return dfs(m - 1, n - 1) # ์ข
์ ์ ์ขํ๋ถํฐ ์์
class Solution(object):
def uniquePaths(self, m, n):
memo = [[-1] * n for _ in range(m)] # col 1์ฐจ์ ๋ฐฐ์ด์ ๋จผ์ ๋ง๋ค๊ณ , row๋ก iterate
def dfs(r, c):
if (r, c) == (0, 0): # base condition
return 1
if memo[r][c] == -1:
unique_paths = 0
# ๊ฒฝ๊ณ๊ฐ์ ๋ฐ๋ก ์ค์ ํด์ค์ผํจ(์๊ทธ๋ฌ๋ฉด, ๊ฐ์ฅ์๋ฆฌ์ ์์๋ ํญ์ ๊ฑฐ์ง์ด๋์ NoneType์ ๋ฐํ)
if r - 1 >= 0: # ์์ชฝ ์
์์ ์ค๋ ๊ฒฝ์ฐ
unique_paths += dfs(r - 1, c)
if c - 1 >= 0: # ์ผ์ชฝ ์
์์ ์ค๋ ๊ฒฝ์ฐ
unique_paths += dfs(r, c - 1)
memo[r][c] = unique_paths
return memo[r][c]
return dfs(m - 1, n - 1)
์ฌ๊ธฐ์ [-1]์ ์ด๊ธฐ๊ฐ์ ์๋ฏธํ๊ณ , ์๋ ์๋ฆฌ๋ (1)๊ณผ ๋๊ฐ๋ค.
โฐ๏ธtop-down ์๊ฐ๋ณต์ก๋: ์ด๋ฏธ ๊ณ์ฐํ ๊ฐ์ memo์ ์ ์ฅํด๋๊ณ , ๊ฒฐ๊ณผ์ ์ผ๋ก grid์ ํด๋นํ๋ ๊ฐ๋ง ๊ณ์ฐํ๋ฏ๋ก O(M*N)
top-down ๋ฐฉ์์์๋ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ฉด์ (0,0)์ ๋๋ฌํ๋ฉด 1์ ๋ฆฌํดํ๋๋ฐ, ์ด๊ฒ์ ํธ์ถํ ํจ์๋ก ๊ณ์ํด์ ์ ๋ฌํ๋ฏ๋ก ์ต์ข ์ ์ผ๋ก ๊ฐ์ฅ์๋ฆฌ๊ฐ 1๋ก ์ฑ์์ง๋ ๊ทธ๋ฆผ์ด ๋๋ค.
class Solution(object):
def uniquePaths(self, m, n):
table = [[-1] * n for _ in range(m)]
# top-down์์ ๊ฐ์ฅ์๋ฆฌ 1๋ก ์ฑ์ด ์์ด๋์ด ํ์ฉ
for r in range(m):
table[r][0] = 1
for c in range(n):
table[0][c] = 1
# ์์ ๋ฌธ์ ๋ค์ ๊ณ์ํด์ ํฉํด์ ํฐ ๋ฌธ์ ๋ก ๋์๊ฐ
for r in range(1, m):
for c in range(1, n):
table[r][c] = table[r - 1][c] = table[r][c - 1]
return table[m - 1][n - 1]
์ฌ๊ธฐ์์๋ ๊ฒฝ๊ณ๊ฐ ๋ฒ์ ์กฐ๊ฑด์ ์ด๋ฏธ 1๋ก ์ฑ์ด ๊ฐ์ฅ์๋ฆฌ์ ์ด์ค for๋ฌธ์ผ๋ก ๋์ฒดํ์๋ค.

if(r, c) == (0, 0):์ ๋์
๋๋ฆฌ ์๋ฃ๊ตฌ์กฐ์ธ table์ ๋ฏธ๋ฆฌ ์ฑ์๋ฃ์return table[(r, c]๋ฅผ ํ๋ฉด ์ต์ข
์ ์ธ ๊ฐ์ ์ป์ ์ ์๋ค.์ฌ๊ธฐ์ ์์ ์์น ๋ ๋ถ๋ถ์ ์ ์ฌํ ์ดํด๋ณด์. ์ด์ค for๋ฌธ์ผ๋ก ์์๋ค์ ์ํํ๊ณ ์๋๋ฐ, ์์ ๋ชจ์๋ฆฌ ๋ถ๋ถ์ ์งํฉ A, ์ผ์ชฝ ๋ชจ์๋ฆฌ๋ฅผ ์งํฉ B, ๊ทธ๋ฆฌ๊ณ top-down์ฒ๋ผ ์๋ ์ + ์ค๋ฅธ์ชฝ ์ ๋ถ๋ถ์ ์งํฉ C๋ผ๊ณ ํ์.
์ฆ, if AโชB:์ if C:๋ฅผ ์ด์ค for๋ฌธ์์ ๋ณ๋ ฌ์ ์ผ๋ก ๋ฐฐ์นํ๋ฉด ๋๋ค.
class Solution(object):
def uniquePaths(self, m, n):
table = {(0, 0): 1} # converted from if (r, c) == (0,0):
def dp(r, c): # (2, 6)
# Don't have to set bounded range because no recursive calls are made to r-1 or c-1
for i in range(r + 1):
for j in range(c + 1):
if i == 0 or j == 0: # Fill both the 1st row and col with 1 (corresponds to A โช B)
table[(i, j)] = table[(0, 0)]
if i > 0 and j > 0: # Combine the cell below and the cell to the right (corresponds to C)
table[(i, j)] = table[(i - 1, j)] + table[(i, j - 1)]
return table[(r, c)]
return dp(m - 1, n - 1)
for r in range(m):
table[r][0] = 1
for c in range(n):
table[0][c] = 1
๐ค๊ทธ๋ฐ๋ฐ, ๊ฒฐ๊ตญ์ ๊ณ ์ ๋ ์ธ๋ฑ์ค์์ ๋ชจ๋ 1๊ฐ์ผ๋ก ์ฑ์ฐ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋์ผํ๋ ๋ด๊ฐ ์ค์ค๋ก ์งฐ๋ ๋ฐฉ์์ผ๋ก ํด๋ ์๊ด ์์ ๋ฏ ํ๋ค.
for r in range(1, m):
for c in range(1, n):
table[r][c] = table[r - 1][c] = table[r][c - 1]
์์ ๊ฐ์ ์ฝ๋๊ฐ ๋์๋ค. ์ฆ, range(1, m)์ผ๋ก 1๋ถํฐ ์์ํ๊ฒ ๋ง๋ค์๋ค๋ ๊ฒ์ด๋ค.
๐ค์ด ๋ถ๋ถ ์ญ์ 1๋ถํฐ ์์ํ๋ ๊ฒ์ ๋์ผํ๊ธฐ ๋๋ฌธ์, if i > 0 and j > 0:๋ก ์ง๋ ๋ฌด๋ฐฉํ๋ค.
โฐ๏ธbottom-up ์๊ฐ๋ณต์ก๋: grid๋ฅผ ์ํํ๋ฉด์ ๊ฐ์ ์ฑ์๋๊ฐ๊ธฐ ๋๋ฌธ์ O(M*N)