백준 1520번:내리막 길, DP 접근

주성천·2024년 6월 22일

문제

백준 1520번: 내리막 길

접근법

올바른 접근법

  • DP 배열에 특정 위치에서 목적지까지 도달할 수 있는 경우의 수를 저장해야 한다.
  • DP의 값이 초기 값 -1이 아니라면(이미 계산된 경로)라면 바로 반환하여 연산 횟수를 줄인다.
  • DFS 메소드의 반환값으로 특정 위치에서 목적지까지의 경로 경우의 수를 반환함으로써 DP에 저장된 값이 목적지까지 이어진 경우의 수를 보장한다.

DP 배열의 모습

DP 배열의 최종 모습

나의 접근 실수

  • DP의 값에 해당 위치까지의 도달하는 경우의 수를 저장하는 방식으로 접근했었다. 그 결과, 목적지까지 이어지지 않은 경우에도 DP에 값을 기록하여서 목적지까지 이어지는 경로만 찾아내는 것이 불가능하였다.

코드

import java.util.*;
import java.io.*;

public class PN1520 {
    static int M;
    static int N;
    static  int[][] map;
    static int[][] dp;
    static final int[] DIR_Y = {1, 0, -1, 0};
    static final int[] DIR_X = {0, 1, 0, -1};
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());
        map = new int[M][N];
        dp = new int[M][N];

        for(int r = 0; r < M; r++) {
            st = new StringTokenizer(br.readLine());
            for(int c = 0; c < N; c++) {
                map[r][c] = Integer.parseInt(st.nextToken());
                dp[r][c] = -1;
            }
        }

        System.out.println(dfs(0, 0));
    }

    static int dfs(int r, int c) {
        if(r == M - 1 && c == N - 1) {
            return 1;
        }

        if(dp[r][c] != -1) {
            return dp[r][c];
        }

        dp[r][c] = 0;

        for(int i = 0; i < 4; i++) {
            int nextY = DIR_Y[i] + r;
            int nextX = DIR_X[i] + c;

            if(nextY < 0 || M <= nextY) continue;
            if(nextX < 0 || N <= nextX) continue;
            if(map[r][c] <= map[nextY][nextX]) continue;

            dp[r][c] += dfs(nextY, nextX);
        }

        return dp[r][c];
    }
}
profile
기록과 정리

0개의 댓글