📙 Algorithm Solving/Java
📙[Algo] 24.03.11 알고리즘
혜덕hyeduck
2024. 3. 12. 09:19
알고리즘 문제) BOJ 1520. 내리막 길
문제 요약
- 여러 칸으로 나뉜 지도가 있음
- 각 칸은 지점을 나타내며, 지점의 높이가 쓰여있다
- 지점끼리는 상하좌우 이동 가능
- 세준이 처음 위치 : (0,0)
- 목적지 : 맨 오른쪽 아래 칸
- 항상 높이가 더 낮은 지점으로만 이동
- 제일 왼쪽 위 지점에서 출발하여 제일 오른쪽 아래 지점까지 항상 내리막길로만 이동하는 경로의 개수 구하기
시간 제한
- 2초
입력
- 지도 세로 크기 M, 가로 크기 N
- M개의 줄에 N개씩 지점의 높이가 주어짐
- M과 N은 500이하 자연수
- 각 지점 높이는 10000이하 자연수
출력
- 이동 가능한 경로의 수 H 출력
- 10억 이하의 음이 아닌 정수
접근법
- 백트랙킹으로 생각하기
- 상하좌우를 살펴 내리막길로 갈 수 있는 경우를 탐색
- recur(int row, int col, int height)
- 이때, row와 col이 M-1, N-1 인 경우에 대해서 카운팅
- 만약 이전 지점의 height와 현재 높이를 비교하여 내리막길이 아닌경우
코드
import java.io.*;
import java.util.*;
public class Main {
static int M, N;
static int[][] arr;
static int[] delR = {-1, 1, 0, 0};
static int[] delC = {0, 0, -1, 1};
static int[][] dp;
// static int answer;
// 1. 백트랙킹으로 풀기
// static void recur(int row, int col, int height) {
//
// if (height <= arr[row][col]) return;
//
// if (row == M - 1 && col == N - 1) {
// answer++;
// return;
// }
//
// int mrow, mcol;
// for (int i = 0; i < 4; i++) {
// mrow = row + delR[i];
// mcol = col + delC[i];
//
// if (mrow < 0 || mcol < 0 || M <= mrow || N <= mcol) continue;
//
// recur(mrow, mcol, arr[row][col]);
// }
//
// }
// 2. 함수 + 메모이제이션 적용
static int recur(int row, int col, int height) {
if (height <= arr[row][col]) return 0;
if (row == M - 1 && col == N - 1) return 1;
if (dp[row][col] != -1) return dp[row][col];
int mrow, mcol;
int ret = 0;
for (int i = 0; i < 4; i++) {
mrow = row + delR[i];
mcol = col + delC[i];
if (mrow < 0 || mcol < 0 || M <= mrow || N <= mcol) continue;
ret += recur(mrow, mcol, arr[row][col]);
}
dp[row][col] = ret;
return dp[row][col];
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
arr = new int[M][N];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
dp = new int[M + 1][N + 1];
for (int i = 0; i < M + 1; i++) {
Arrays.fill(dp[i], -1);
}
// recur(0,0, 10010);
// bw.write(String.valueOf(answer));
bw.write(String.valueOf(recur(0,0,10001)));
bw.flush();
bw.close();
br.close();
}
}