알고리즘/문제풀이
[백준/BOJ] 1520 내리막 길 - JAVA - 골드3
LIRI
2024. 5. 29. 18:24
[백준/BOJ] 1520 내리막 길 - JAVA - 골드3
문제
https://www.acmicpc.net/problem/1520
문제 분석
조건
- 왼쪽 위에서 시작하여 오른쪽 아래로 이동하는 것이 목표
- 현재 숫자보다 작은 인접한 숫자로만 이동할 수 있음
- 가능한 경로의 수를 출력
풀이방법
- DFS를 이용하여 경로를 탐색하며 DP를 이용하여 방문했던 점엔 다시 방문하지 않는 방법을 이용했습니다.
DP 테이블을 -1로 초기화 한 뒤 출발지점부터 탐색을 시작
현재 좌표에 이미 방문을 했으면 현재 좌표의 DP값을 반환하고, 첫 방문(-1)일 시 0으로 DP값을 업데이트
DFS 탐색을 시계방향으로 했을 때 아래와 같은 상황이 된다.
방법을 반복하여 목표 지점에 도달하였을 경우 1를 반환하고 이를 이전 좌표 DP값에 업데이트 한다.
DP값을 업데이트 하여 돌아갈때 `[0, 3]`좌표에서는 아래 방향으로 한번 더 탐색을 할 수 있게 된다. 이때는 방문하지 않고 방문해야할 지점인 DP[1, 3]의 값을 현재 DP값으로 더하면 된다.
같은 방법으로 계속 진행하여 아래를 탐색하면
위와 같은 모양이 되고, 같은 방법으로 방문해야할 지점의 DP값이 -1이 아니면 해당 값을 현재 DP값으로 더하면 된다.
최종적으로 DP 표는 위와 같은 모양이 되며, `[0, 0]`의 값인 3이 답이 된다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int R;
static int C;
static int[][] map;
static int[][] dp;
static int[][] dr = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new int[R][C];
dp = new int[R][C];
for (int r = 0; r < R; r++) {
st = new StringTokenizer(br.readLine());
Arrays.fill(dp[r], -1);
for (int c = 0; c < C; c++) {
map[r][c] = Integer.parseInt(st.nextToken());
}
}
System.out.println(dfs(0, 0));
}
private static int dfs(int r, int c) {
if (r == R - 1 && c == C - 1) {
return 1;
}
if (dp[r][c] != -1) {
return dp[r][c];
}
dp[r][c] = 0;
for (int[] d : dr) {
int nextR = r + d[0];
int nextC = c + d[1];
if (nextR < 0 || nextC < 0 || nextR >= R || nextC >= C) {
continue;
}
if (map[r][c] > map[nextR][nextC]) {
if (dp[nextR][nextC] != -1) {
dp[r][c] += dp[nextR][nextC];
continue;
}
dp[r][c] += dfs(nextR, nextC);
}
}
return dp[r][c];
}
}
결과
728x90