알고리즘/BAEKJOON

[백준] 1520 내리막 길 (Java)

kyeee2 2022. 4. 4. 14:01

[1520 내리막 길]

난이도: 골드4

 

1520번: 내리막 길

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

www.acmicpc.net

문제

입력

출력


[아이디어]

처음에는 일반 DFS로 풀었다가 시간 초과가 났다. (다시 생각해보니 대략 500 * 500 * 500 * 500 * 4 정도의 시간이 걸리므로 시간 초과가 나는 것은 당연했다.)

시간 초과가 났기 때문에 DP로 풀어야 하나는 것은 알아챘지만 어떻게 DP를 적용해야 하는지 모르겠어서 구글링을 해봤다.

 

이 분이 설명을 위해 만들어 놓은 애니메이션으로 접근 방법을 알아 차릴 수 있었다.

 

[백준][1520번][DP] 내리막길

내리막길 https://www.acmicpc.net/problem/1520 <코드> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51..

wootool.tistory.com


[JAVA 코드]

위의 블로그를 통해 이해하고 DP를 적용한 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokens;
	
	static int N, M;
	static int [][] map;
	static int [][] D;
	static int [] dr = {-1, 0, 1, 0}, dc = {0, 1, 0, -1};
	
	public static void main(String[] args) throws IOException {
		tokens = new StringTokenizer(br.readLine());
		N = Integer.parseInt(tokens.nextToken());
		M = Integer.parseInt(tokens.nextToken());
		
		map = new int [N][M];
		D = new int [N][M];
		for(int r = 0; r < N; r++) {
			tokens = new StringTokenizer(br.readLine());
			for(int c = 0; c < M; c++) {
				map[r][c] = Integer.parseInt(tokens.nextToken());
				D[r][c] = -1; // 초기화
			}
		}
		
		System.out.println(dfs(0, 0));
	}

	private static int dfs(int r, int c) {
		if(r == N - 1 && c == M - 1) return 1;
		if(D[r][c] != -1) return D[r][c];
		
		D[r][c] = 0;
		for(int i = 0; i < 4; i++) {
			int nr = r + dr[i];
			int nc = c + dc[i];
			
			if(nr < 0 || nr >= N || nc < 0 || nc >= M || map[r][c] <= map[nr][nc]) continue;
			
			D[r][c] += dfs(nr, nc);
		}
		
		return D[r][c];
	}

}

 

처음에 시간 초과가 난 일반 dfs 코드

더보기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokens;
	
	static int N, M, cnt = 0;
	static int [][] map;
	static int [] dr = {-1, 0, 1, 0}, dc = {0, 1, 0, -1};
	
	public static void main(String[] args) throws IOException {
		tokens = new StringTokenizer(br.readLine());
		N = Integer.parseInt(tokens.nextToken());
		M = Integer.parseInt(tokens.nextToken());
		
		map = new int [N][M];
		for(int r = 0; r < N; r++) {
			tokens = new StringTokenizer(br.readLine());
			for(int c = 0; c < M; c++) {
				map[r][c] = Integer.parseInt(tokens.nextToken());
			}
		}
		
		dfs(0, 0);
		
		System.out.println(cnt);
	}

	private static void dfs(int r, int c) {
		if(r == N - 1 && c == M - 1) {
			cnt++;
			return;
		}
		
		for(int i = 0; i < 4; i++) {
			int nr = r + dr[i];
			int nc = c + dc[i];
			
			if(nr < 0 || nr >= N || nc < 0 || nc >= M || map[r][c] <= map[nr][nc]) continue;
			
			dfs(nr, nc);
		}
	}
}