https://www.acmicpc.net/problem/1520

 

1520번: 내리막 길

첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다.

www.acmicpc.net

코드설명

DFS와 DP를 활용하는 문제입니다.

 

처음에 문제를 보고 BFS로 Visited[][][4] 로 처리하였지만, 이렇게 할경우 같은방향으로 들어오는경우도 처리가 올바르게 되지 않아 작동하지 않습니다.

그렇기에, 위와 같은 BFS와 중복처리로도 해결되지 않습니다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static int N, M;
public static int answer = 0;
public static int[][] arr;
public static int[] dx = { -1, 1, 0, 0}; //상하좌우
public static int[] dy = { 0, 0, -1, 1};
public 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());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[N][M];
dp = new int[N][M];
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
for(int j=0;j<M;j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
dp[i][j] = -1;
}
}
answer = DFSWithDp(0, 0);
System.out.println(answer);
}
public static int DFSWithDp(int startX, int startY) {
if( startX == N -1 && startY == M - 1) {
return 1;
}
if(dp[startX][startY] != -1) { //이미 계산된 구간이라면 해당 구간에서 (N, M)까지의 경로의 개수를 바로 가져올 수 있습니다.
return dp[startX][startY];
}
dp[startX][startY] = 0; //해당 점에서 (N,M)까지 0 이라고 초기화시키며 방문처리를 합니다.
for(int dir= 0; dir<4;dir++) {
int nx = startX + dx[dir];
int ny = startY + dy[dir];
if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue; //범위체크
if(arr[startX][startY] <= arr[nx][ny] ) continue; //만약 내리막길이 아니라면 중단
dp[startX][startY] += DFSWithDp(nx, ny ); //내리막길일경우 실행. 다음 위치가 이미 계산된 경우라면 DP배열을 통해 값을 바로 가져옵니다.
}
return dp[startX][startY]; //만약 해당 지점에서 더이상 이동할 수 없다면 본인의 DP값을 반환하여 종료시킵니다.
}
}

+ Recent posts