알고리즘 연습/DFS와 BFS

[🥇3 / 백준 1937 / 파이썬] 욕심쟁이 판다

김세진 2021. 10. 16. 00:19
반응형

 

 

1937번: 욕심쟁이 판다

n × n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에

www.acmicpc.net

 

문제

n × n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다.

이 판다의 사육사는 이런 판다를 대나무 숲에 풀어 놓아야 하는데, 어떤 지점에 처음에 풀어 놓아야 하고, 어떤 곳으로 이동을 시켜야 판다가 최대한 많은 칸을 방문할 수 있는지 고민에 빠져 있다. 우리의 임무는 이 사육사를 도와주는 것이다. n × n 크기의 대나무 숲이 주어져 있을 때, 이 판다가 최대한 많은 칸을 이동하려면 어떤 경로를 통하여 움직여야 하는지 구하여라.

입력

첫째 줄에 대나무 숲의 크기 n(1 ≤ n ≤ 500)이 주어진다. 그리고 둘째 줄부터 n+1번째 줄까지 대나무 숲의 정보가 주어진다. 대나무 숲의 정보는 공백을 사이로 두고 각 지역의 대나무의 양이 정수 값으로 주어진다. 대나무의 양은 1,000,000보다 작거나 같은 자연수이다.

출력

첫째 줄에는 판다가 이동할 수 있는 칸의 수의 최댓값을 출력한다.

 

예제 입력 

4
14 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)
반응형