본문 바로가기

알고리즘/백준 문제 풀이

[Python] 1520번 내리막 길

728x90

https://www.acmicpc.net/problem/1520


 

24/11/13

 

 

무난한 DP이다. 처음에는 바텀업으로 생각했으나, 잘 생각나지 않아서 탑다운으로 짰다.


 

문제 접근 방식:

 

 

DP식을 다음과 같이 정의하자.

 

DP[i][j] = $(i, j)$번째 칸에 왔을 때 항상 내리막 길로만 오는 경우의 수.

 

우리의 목적은 $DP[N-1][M-1]$의 값을 구하는 것이다.

 

또한, $DP[0][0] = 1$임을 알고 있다.

 

내리막 길로 간다는 것은 현재 칸보다 이전의 칸에 쓰여있는 숫자가 더 크다는 뜻이다.

 

따라서, 기본적으로 현재 칸을 둘러싸고 있는 4개의 주변 칸, 즉, 이전의 칸에 쓰여있는 숫자가 더 크다면, 그 칸을 통해 현재 칸으로 올 수 있다.

 

따라서, 4개의 주변 칸에 대해서 DP값을 찾아주고, 그 값을 전부 더한 값이 DP[i][j]의 값이 된다.

 

이를 토대로 탑다운 DP를 돌리면 되고, 파이썬의 경우 재귀 깊이의 제한이 있으니 이에 유의하여 재귀깊이를 설정해주면 될 것이다.


아래는 내가 위의 접근 방식과 같이 작성한 파이썬 코드이다. 더보기를 누르면 확인할 수 있다.

더보기
# 1520번 내리막 길
# DP
import sys
input = sys.stdin.readline
sys.setrecursionlimit(500_000)

N, M = map(int, input().split())
G = [list(map(int, input().split())) for _ in range(N)]
DP = [[-1 for _ in range(M)] for _ in range(N)]
dr, dc = [-1, 1, 0, 0], [0, 0, -1, 1]
DP[0][0] = 1
def dfs(i, j):
    K = 0
    if DP[i][j] != -1:
        return DP[i][j]
    for k in range(4):
        ni, nj = i+dr[k], j+dc[k]
        if 0 <= ni < N and 0 <= nj < M and G[i][j] < G[ni][nj]:
            if DP[ni][nj] == -1:
                dfs(ni, nj)
            K += DP[ni][nj]
    DP[i][j] = K
    return DP[i][j]
dfs(N-1, M-1)
print(DP[N-1][M-1])

'알고리즘 > 백준 문제 풀이' 카테고리의 다른 글

[Python] 1178번 간선 추가  (0) 2024.11.15
[Python] 2418번 단어 격자  (0) 2024.11.14
[Befunge] 2380번 Star  (0) 2024.11.12
[Python] 32645번 동까뚱뽭 게임  (0) 2024.11.11
[Python] 32299번 게임을 만들어요  (0) 2024.11.10