dfs + dp (memoization)으로 풂
memoization을 사용하는 이유: 불필요하게 반복적으로 재귀하여 탐색하는 경우를 막고자, dp table에 한 번 갔던 곳의 dfs 결과 값을 저장하여 이를 재사용하기 위함이다
dp table에는 해당 위치에서 판다가 이동할 수 있는 칸의 최대 개수가 저장되어야한다
구현 흐름
-> dp table을 -1로 초기화하고 2중 for문을 돌며 dfs를 호출한다
-> dp[x][y]가 갱신되어있는 상태라면 dp[x][y]는 해당 위치에서 판다가 이동할 수 있는 칸의 최대 개수임을 보장하기 때문에, 더이상 탐색을 하지 않고 바로 dp[x][y]를 반환해준다
-> 그렇지 않다면 상하좌우를 탐색하면서 조건에 맞는 경우에 dfs(nx, ny)를 호출해주고, 그 중 최댓값 + 1(현재 칸도 포함)을 dp[x][y]에 할당해주고 이를 반환해준다
4
14 9 12 10
1 11 5 4
7 15 2 13
6 3 16 8
[[1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]]
[[1, 3, 1, -1], [-1, 2, -1, -1], [-1, 1, -1, -1], [-1, -1, -1, -1]]
[[1, 3, 1, 2], [-1, 2, -1, -1], [-1, 1, -1, -1], [-1, -1, -1, -1]]
[[1, 3, 1, 2], [3, 2, -1, -1], [2, 1, -1, -1], [-1, -1, -1, -1]]
[[1, 3, 1, 2], [3, 2, 3, -1], [2, 1, -1, -1], [-1, -1, -1, -1]]
[[1, 3, 1, 2], [3, 2, 3, 4], [2, 1, -1, 1], [-1, -1, -1, -1]]
[[1, 3, 1, 2], [3, 2, 3, 4], [2, 1, 4, 1], [-1, -1, 1, -1]]
[[1, 3, 1, 2], [3, 2, 3, 4], [2, 1, 4, 1], [3, -1, 1, -1]]
[[1, 3, 1, 2], [3, 2, 3, 4], [2, 1, 4, 1], [3, 4, 1, -1]]
[[1, 3, 1, 2], [3, 2, 3, 4], [2, 1, 4, 1], [3, 4, 1, 2]] -> 최종 dp table
import sys
sys.setrecursionlimit(10**6)
dx = (-1, 1, 0, 0)
dy = (0, 0, -1, 1)
def dfs(x, y):
if dp[x][y] != -1:
return dp[x][y]
cnt = 0
for i in range(4):
nx = x + dx[i]; ny = y + dy[i]
if 0 <= nx < N and 0 <= ny < N:
if board[nx][ny] > board[x][y]:
cnt = max(cnt, dfs(nx, ny))
dp[x][y] = cnt + 1 #현재 칸도 포함
return dp[x][y]
N = int(sys.stdin.readline()[:-1])
board = []
for n in range(N):
board.append(list(map(int, sys.stdin.readline()[:-1].split())))
dp = [[-1] * N for _ in range(N)]
max_cnt = 0
for i in range(N):
for j in range(N):
if dp[i][j] == -1:
max_cnt = max(max_cnt, dfs(i, j))
print(max_cnt)