728x90
해당 문제는 자력으로 푼 건 아니고 다른 분의 풀이를 참고하여 푼 것이다. 왜 Queue를 사용한 bfs는 안되는 걸까 생각하다가 힙을 쓰면 된다고 생각하니 풀렸다. 정석으로는 탑다운 방식의 DP였다.
<문제 풀이/접근과정>
1. 내리막길의 개념은 현재 방문한 곳의 높이(값) 보다 다음에 방문할 곳의 값이 더 낮은 경우이다.
2. BFS+DP또는 DFS+DP로 풀면 된다.
3. 두 가지 접근법이 있는데 0,0(시작점-바텀업) 부터 아래로 쌓거나, M-1, N-1(도착점-탑다운)부터 쌓으면 된다.
4. 해당 문제는 dp다 보니까 탑다운, 바텀업 전부 되지만 나는 바텀업(0,0 부터 쌓기)방식으로 풀었다.
5. PriorityQueue를 쓰지 않으면 주변 내리막길이란 내리막길은 다 가기 때문에내리막길 다음의 그다음 제일 큰 내리막길로 가게끔 해서 자동으로 경로의 수를 쌓게 하는 방식이다.
<소스 코드>
package boj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
public class Boj_1520 {
static int M, N, arr[][], delta[][] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }, dp[][];
public static void main(String[] args) throws IOException {
StringTokenizer stz;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
stz = new StringTokenizer(br.readLine());
M = Integer.parseInt(stz.nextToken());
N = Integer.parseInt(stz.nextToken());
arr = new int[M][N];
dp = new int[M][N];
for (int i = 0; i < M; i++) {
stz = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
arr[i][j] = Integer.parseInt(stz.nextToken());
}
}
bfs(0, 0);
System.out.println(dp[M - 1][N - 1]);
}
private static void bfs(int startR, int startC) {
PriorityQueue<int[]> q = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return arr[o2[0]][o2[1]] - arr[o1[0]][o1[1]];
}
});
dp[0][0] = 1;
q.add(new int[] { startR, startC });
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
int temp[] = q.poll();
int r = temp[0];
int c = temp[1];
if (r == M - 1 && c == N - 1)
continue;
for (int j = 0; j < delta.length; j++) {
int nr = r + delta[j][0];
int nc = c + delta[j][1];
if (!check(nr, nc)) continue;
if (arr[r][c] > arr[nr][nc]) {
if(dp[nr][nc] == 0) q.add(new int[] { nr, nc });
dp[nr][nc] += dp[r][c];
}
}
}
}
}
private static boolean check(int nr, int nc) {
return 0 <= nr && nr < M && 0 <= nc && nc < N;
}
}
728x90
'알고리즘공부(Algorithm Study) > 문제풀이(ProblemSolving)' 카테고리의 다른 글
백준 24444 & 24445 알고리즘 수업 - 너비 우선 탐색1 & 너비우선 탐색 2 (0) | 2022.05.28 |
---|---|
백준 24479 & 24480 알고리즘 수업 - 깊이 우선 탐색 1&2(DFS) (0) | 2022.05.24 |
백준 11049 java - 행렬 곱셈 순서(DP/동적계획법) (0) | 2022.05.22 |
백준 1358 java - 하키(기하/백준단계별로풀기 기하 clear) (0) | 2022.05.19 |
백준 1004 java - 어린왕자(기하) (0) | 2022.05.18 |
댓글