문제
n × n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다.
이 판다의 사육사는 이런 판다를 대나무 숲에 풀어 놓아야 하는데, 어떤 지점에 처음에 풀어 놓아야 하고, 어떤 곳으로 이동을 시켜야 판다가 최대한 많은 칸을 방문할 수 있는지 고민에 빠져 있다. 우리의 임무는 이 사육사를 도와주는 것이다. n × n 크기의 대나무 숲이 주어져 있을 때, 이 판다가 최대한 많은 칸을 이동하려면 어떤 경로를 통하여 움직여야 하는지 구하여라.
입력
첫째 줄에 대나무 숲의 크기 n(1 ≤ n ≤ 500)이 주어진다. 그리고 둘째 줄부터 n+1번째 줄까지 대나무 숲의 정보가 주어진다. 대나무 숲의 정보는 공백을 사이로 두고 각 지역의 대나무의 양이 정수 값으로 주어진다. 대나무의 양은 1,000,000보다 작거나 같은 자연수이다.
출력
첫째 줄에는 판다가 이동할 수 있는 칸의 수의 최댓값을 출력한다.
예제 입력414 9 12 10 1 11 5 4 7 15 2 13 6 3 16 8 |
예제 출력4 |
풀이
DFS와 DP를 동시에 활용하는 문제이다.
계속 시도해도 시간초과가 나서 다른 분의 코드를 참고했다.
알고 보니 반대로 하고 있었다.
DP에는 현재 노드부터 DFS를 진행했을 때, 최대로 움직일 수 있는 칸이 몇인지 기록한다.
필자는 반대로 DP에 DFS의 깊이를 넣고 있었다. 이러니 시간초과가 날 수밖에..
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
n = int(input())
board = [list(map(int,input().split())) for _ in range(n)]
dp = [[-1]*n for _ in range(n)]
move = [(0,1),(1,0),(0,-1),(-1,0)]
ans = 0
def dfs(x,y):
if dp[x][y] == -1:
dp[x][y] = 0
for a,b in move:
dx=x+a; dy=y+b
if n>dx>=0 and n>dy>=0 and board[dx][dy] > board[x][y]:
dp[x][y] = max(dp[x][y],dfs(dx,dy))
return dp[x][y]+1
for i in range(n):
for j in range(n):
ans = max(ans,dfs(i,j))
print(ans)
'알고리즘 연습 > DFS와 BFS' 카테고리의 다른 글
[🥇1 / 백준 1194 / 파이썬] 달이 차오른다, 가자. (0) | 2021.11.02 |
---|---|
[🥇3 / 백준 9466 / 파이썬] 텀 프로젝트 (0) | 2021.10.20 |
[🥇5 / 백준 2636 / 파이썬] 치즈 (0) | 2021.10.15 |
[🥇5 / 백준 2589 / 파이썬] 보물섬 (0) | 2021.10.15 |
[🥇4 / 백준 2573 / 파이썬] 빙산 (0) | 2021.10.14 |