백준 - 1520

Rivelog·2023년 11월 12일
0

코딩 테스트

목록 보기
9/11

문제

문제

입력/출력

입출력

풀이

상하좌우의 칸에 현재 값과 비교를 하기위해 dx/dy를 쓰고,
계산 시간 단축을 위해 동적 계획법을 사용한다.

?)동적 계획법:중복되는 지점들을 캐싱하여 중복 계산을 줄여서 효율성을 높이는 방법

1부터 5까지의 경로 수를 구할 때 3까지 가는 경로의 수를 저장하여 중복계산을 줄인다

dp의 값을 모두 -1로 초기화한다. 탐색을 할때 map과 같은 좌표의 dp 값이 -1인 경우와 아닌 경우를 구별한다.
-1인 경우에는 한번도 방문하지 않은 경로라는 의미기 때문에 같은 값의 지도 좌표에서 4방탐색하여 더 작은 곳이 있는지 확인하고 작은 곳으로 이동한다. 이때 경로의 수를 더 해준다.
dp가 -1이 아닌 경우는 현재 dp에 저장된 값을 반환해준다.

코드

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

class Main {
    static int M, N;
    static int[][] map;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, 1, -1};
    static int[][] dp;

    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 + 1][N + 1];
        dp = new int[M + 1][N + 1];
        for (int i = 1; i <= M; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken()); // 지도 좌표 입력
                dp[i][j] = -1; // dp는 모든 값을 -1로 초기화
            }
        }
        System.out.println(DFS(1,1));
    }



    public static int DFS(int x, int y) {
        if (x == M && y == N) {
            return 1;
        }
        if(dp[x][y]!=-1){ //방문한 칸이면 리턴하여 계산 시간 단축
            return dp[x][y];
        }
        else {// -1 일때만 방문
            dp[x][y] = 0; //방문 표시
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                if (nx < 1 || ny < 1 || nx > M || ny > N) { // 4방 탐색 범위설정
                    continue;
                }
                if (map[nx][ny] < map[x][y]) { //현재 값이 4방 탐색 값보다 큰 경우
                    dp[x][y] += DFS(nx,ny); // 현재까지의 경로의 수를 저장
                }
            }
        }
        return dp[x][y]; 총 경로 경우의 수 반환
    }
}

오답 코드 (시간 초과) dp를 사용하지않는 경우

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

class Main {
    static int M, N;
    static int[][] map;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, 1, -1};
    static int count = 0;

    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 + 1][N + 1];
        for (int i = 1; i <= M; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        DFS(1, 1);
        System.out.println(count);
    }

    public static void DFS(int x, int y) {
        if (x == M && y == N) {
            count++;
        }
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx < 1 || ny < 1 || nx > M || ny > N) {
                continue;
            }
            if (map[nx][ny] < map[x][y]) {
                DFS(nx, ny);
            }
        }
    }
}
profile
Just Do It

0개의 댓글