백준 1520번 - 내리막 길

장근영·2024년 6월 24일
0

BOJ - DP

목록 보기
5/38

문제

백준 1520번 - 내리막 길


아이디어

  • DFS + DP
  • 단순하게 DFS나 BFS로 풀면 시간초과가 발생한다.
  • 단순 DFS라면 끝점만 찍고 오면 끝이겠지만 이 문제의 경우 가능한 모든 경로의 개수를 구하는 것이므로 메모이제이션을 사용해야 한다.
  • dp 배열을 현재 자리에서 도착 지점까지 갈 수 있는 경로의 개수라고 가정한다.
  • 메모이제이션을 사용하면 처음 도착 지점까지 갈 수 있는 경로를 확인하고 또 다른 경로를 확인할 때 다시 처음부터 확인하지 않고 가능했던 경로에 이어서 또 다른 경로를 확인할 수 있다.

예상 시간 복잡도

  • 메모이제이션을 사용하여 모든 지점에 대해 한번씩만 확인 가능하다.
  • 예상 시간 복잡도 : O(M x N)

코드 구현

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BJ_1520 {

    static int[][] map;
    static int m, n;
    static int[][] dp;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 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 i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                dp[i][j] = -1;
            }
        }

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

    private static int dfs(int x, int y) {
        if (x == m - 1 && y == n - 1) { //도착 지점 가능, 경우의 수 추가
            return 1;
        }

        if (dp[x][y] != -1) { //dp 배열을 방문 체크의 용도로도 가능하다.
            return dp[x][y];
        }

        dp[x][y] = 0; //가능한 경로 방문 확인

        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (nx >= 0 && nx < m && ny >= 0 && ny < n) { //범위 체크
                if (map[nx][ny] < map[x][y]) { //조건 체크
                    dp[x][y] += dfs(nx, ny); //현재 위치에서 가능한 경로의 개수 합
                }
            }
        }

        return dp[x][y];
    }
}

profile
오늘 할 일을 내일로 미루지 말자.

0개의 댓글