https://www.acmicpc.net/problem/1937
1937번: 욕심쟁이 판다
n × n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에
www.acmicpc.net
백준 - 욕심쟁이 판다 (1937번)
난이도 : Gold 3
알고리즘&자료구조 : DFS (깊이 우선 탐색) & Dynamic Programming (동적계획법, DP)
풀이 소요시간 : 25분
import sys
input = sys.stdin.readline
sys.setrecursionlimit(pow(10, 9))
def adjs(r, c):
if 0 < r: yield r-1, c
if 0 < c: yield r, c-1
if r < n-1: yield r+1, c
if c < n-1: yield r, c+1
def dfs(r, c):
maxy = 0
for rr, cc in adjs(r, c):
if forest[rr][cc] <= forest[r][c]:
continue
if memo[rr][cc]:
maxy = max(maxy, memo[rr][cc])
else:
maxy = max(maxy, dfs(rr, cc))
memo[r][c] = maxy + 1
return memo[r][c]
if __name__ == '__main__':
n = int(input())
forest = [list(map(int, input().split())) for _ in range(n)]
memo = [[0]*n for _ in range(n)]
for r in range(n):
for c in range(n):
if memo[r][c]:
continue
dfs(r, c)
print(max(max(r) for r in memo))
DFS와 DP를 활용하는 문제이다.
(1, 1) 칸부터 (n, n) 칸까지 하나씩 확인하면서
이전에 해당 칸에 dfs를 통해 방문한 적이 없다면,
해당 칸에 dfs 함수를 적용한다.
▶ dfs 함수
dfs 함수는, 입력받은 칸에 대해서 상하좌우 인접칸들을 탐색한다.
인접칸의 값이 입력칸보다 작거나 같다면, 판다가 이동할 수 없기 때문에 그냥 넘어간다.
값이 입력칸보다 큰 나머지 인접칸들 중, 가장 큰 memo 값을 가져와서 1을 더하고
memo[입력칸] = (인접칸 중 가장 큰 값 + 1) 로 업데이트 한다.
(만약 인접칸의 memo 값이 0이라면, dfs로 방문한 적이 없으므로
해당 칸에 dfs 함수를 적용해서 memo 값을 업데이트 해준다.)
만약 입력칸보다 큰 인접칸이 없다면,
memo[입력칸] = 1 이 된다.
출력
memo에서 가장 큰 값을 출력하면, 그것이 정답이다.
'Algorithm' 카테고리의 다른 글
메뉴 리뉴얼 (72411번) - 프로그래머스 (Programmers) (0) | 2023.06.23 |
---|---|
카드 짝 맞추기 (72415번) - 프로그래머스 (Programmers) (0) | 2023.06.21 |
광고 삽입 (72414번) - 프로그래머스 (Programmers) (0) | 2023.06.19 |
기타 레슨 (2343번) - 백준 (BOJ) (0) | 2023.06.18 |
합승 택시 요금 (72413번) - 프로그래머스 (Programmers) (0) | 2023.06.17 |