본문 바로가기

알고리즘/DFS&BFS(깊이&너비 우선 탐색)

백준_욕심쟁이판다_1937

문제 링크

조건

  •  n  : 대나무 숲 크기, 1~500 이하
  • 현재 칸보다 대나무가 더 많은 칸으로만 이동 가능

 

접근 방법

  • 메모이제이션 활용
    • memo 배열에 현재 칸(i, j)에서 출발했을 때 최대 몇일 살아남을 수 있는지 저장하며 시간을 단축

 

솔루션

public class Main_1937_욕심쟁이판다 {
	static int N;
	static int[][] map, memo;
	static int K;//판다가 살아남을 수 있는 day 수
	static int[] dr = {-1,1,0,0};
	static int[] dc = {0,0,-1,1};
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine().trim());
		
		map = new int[N][N];
		memo = new int[N][N];//(i,j)에서 출발했을 때 최대 몇일 살아남을 수 있는지 저장
		
		for(int i = 0; i < N; i++) {//map에 대나무 개수 입력
			StringTokenizer st = new StringTokenizer(br.readLine().trim(), " ");
			for(int j = 0; j < N; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				K = Math.max(dfs(i,j), K);
			}
		}
		
		System.out.println(K+1);
		
	}
	
	private static int dfs(int r, int c) {
		if(memo[r][c] > 0) return memo[r][c];//메모 기록이 있다면 return
		int nr,nc;
		
		int max = 0;
		for(int i = 0; i < 4; i++) {
			nr = r + dr[i];
			nc = c + dc[i];
			
			//범위에서 벗어나거나 || 대나무 수가 현재 있는 지점보다 적거나
			if(nr < 0 || nr >= N || nc < 0 || nc >= N || map[nr][nc] <= map[r][c]) continue;

			max = Math.max(max, dfs(nr,nc) + 1);
		}
		
		return memo[r][c] = max;//사방 탐색 후 최대값 저장
	}
}

 

리뷰

  • 처음에는 memo배열에 현재 칸부터 dfs 돌면서 depth를 저장함 => 시간초과
    • dfs으로 최대 값을 구하는 경우, 끝까지 가봐야 알기 때문에 시간초과가 날 가능성이 높음
  • memo 배열에 현재 칸에서 출발했을 때 최대 몇일 살아남을 수 있는지를 저장해야 함 => 메모이제이션

'알고리즘 > DFS&BFS(깊이&너비 우선 탐색)' 카테고리의 다른 글

백준_가르침_1062  (1) 2021.01.27
백준_암호만들기_1759  (0) 2021.01.25
백준_비숍_1799  (0) 2021.01.18
백준_미로만들기_2665  (0) 2021.01.13
백준_부등호_2529  (0) 2021.01.06