# 1937 욕심쟁이 판다 실패(Fail)
def dfs(x,y):
global N
stack = [(x,y,0)]
last_direction = []
while stack:
cx,cy,distance = stack.pop()
flag = True
for i in range(4):
nx = cx + dx[i]
ny = cy + dy[i]
if 0 <= nx<N and 0<=ny<N:
if bamboo[cx][cy] < bamboo[nx][ny]:
if dp[nx][ny] == -1:
stack.append((nx,ny,distance+1))
else:
if distance + dp[nx][ny] + 1 > dp[x][y]:
dp[x][y] = dp[nx][ny] + distance + 1
flag = False
if flag:
if dp[x][y] < distance + 1:
dp[x][y] = distance + 1
N = int(input())
dx = [-1,1,0,0]
dy = [0,0,-1,1]
bamboo = [list(map(int,input().split())) for _ in range(N)]
dp = [[-1]*N for _ in range(N)]
result = - 1
for x in range(N):
for y in range(N):
if dp[x][y] == -1:
dfs(x,y)
print(max(map(max,dp)))
이 문제를 단순하게 DFS로 풀면 시간 초과가 날수 밖에 없다. 왜냐하면 입력이 최대가 500*500 이므로, dp를 통해 이미 탐색한 값들을 저장해놓는 과정이 필요하다. 위의 코드는 시간초과가 난 코드이다.
dp를 사용하긴 했지만, 각 (x,y) 축에서 dfs를 하지만, 이 이동경로에 있는 좌표들에 대해서 이미 한번 측정한 값인데, 다시 한번 dp를 측정해야하는 것이다.
import sys
def dfs(x,y):
if dp[x][y] != -1:
return dp[x][y]
else:
dp[x][y] = 1
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<N and 0<=ny<N:
if bamboo[nx][ny]>bamboo[x][y]:
distance = dfs(nx,ny) + 1
dp[x][y] = max(distance,dp[x][y])
return dp[x][y]
N = int(input())
dx = [-1,1,0,0]
dy = [0,0,-1,1]
bamboo = [list(map(int,input().split())) for _ in range(N)]
dp = [[-1]*N for _ in range(N)]
result = - 1
for x in range(N):
for y in range(N):
if dp[x][y] == -1:
dfs(x,y)
print(max(map(max,dp)))
재귀를 이용한, 이동 경로에 대해서 전부 한번에 업데이트를 해주는 것이다.
최초 이동경로에서 (x0,y0) = > (x1,y1) => (x2,y2) => ...=>(xn,yn) 각 경로마다 최대로 갈수 있는 이동경로들을 저장해준다. 그리고 return된 값에 + 1을 해줘 해당 칸에 갔을때의 이동거리를 측정해주고, 최대값을 갱신해주면 된다.
이렇게 하면 장점은 어느 곳에서 한번 방문했던 곳은 더 이상 dfs를 하지않고 해당 위치에서의 최대값을 반환해주는 것이다.
이 문제는 각 위치마다의 최대경로를 구하는 로직과, 그걸 이용해서 시간복잡도를 줄이는게 중요한 문제였다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 14503 로봇 청소기 (0) | 2021.02.16 |
---|---|
[BOJ/백준] 16946 벽 부수고 이동하기 4 (0) | 2021.02.16 |
[BOJ/백준] 9466 텀 프로젝트 (0) | 2021.02.15 |
[BOJ/백준] 1759 암호 만들기 (0) | 2021.02.15 |
[BOJ/백준] 1991 트리 순회 (0) | 2021.02.15 |