[백준 1937] 욕심쟁이 판다(Java)

최민길(Gale)·2023년 2월 6일
1

알고리즘

목록 보기
33/172

문제 링크 : https://www.acmicpc.net/problem/1937

이 문제는 dfs와 dp를 이용하여 풀 수 있습니다.

큐에 최대 1,000,000 이하의 데이터들이 500X500 배열 내에 존재하기 때문에 만약 bfs로 접근하게 된다면 2차적으로 큐에 데이터들이 저장되기 때문에 메모리 초과가 발생합니다. 따라서 별도의 메모리를 할당하지 않아 메모리는 절약할 수 있는 dfs 방식으로 접근하게 되면 인접 행렬 방식으로 접근하기 때문에 O(V^2)로 여기서 V는 모든 정점의 개수인 500^2의 값이므로 시간복잡도는 500^4 = 625억으로 주어진 시간인 2초를 초과하게 됩니다. 따라서 dp를 이용하여 이미 계산한 결과를 저장하여 dfs 연산을 거치지 않고 배열에서 값을 가져와 출력하는 방식으로 시간을 줄일 수 있습니다.

다음은 코드입니다.

import java.util.*;
import java.io.*;

public class Main{
    static int n;
    static int res = 0;
    static int[][] req = new int[501][501];
    static int[][] dp = new int[501][501];
    static int[] dx = {1,0,-1,0};
    static int[] dy = {0,1,0,-1};

    // 큐에 데이터를 넣는 bfs를 사용할 경우 메모리 초과 발생
    // 따라서 dfs 후 dp를 이용하여 시간 절약
    static int dfs(int y, int x){
        // 만약 dp 배열 내에 이전에 방문한 값이 있다면 해당 값 출력
        if(dp[y][x] != 0) return dp[y][x];
        else{
            // 최초 칸에서 1만큼은 살 수 있음
            dp[y][x] = 1;

            for(int i=0;i<4;i++){
                int ny = y + dy[i];
                int nx = x + dx[i];
                if(ny<0 || ny>=n || nx<0 || nx>=n) continue;

                // 대나무가 많이 있는 지역으로 이동
                if(req[ny][nx] > req[y][x]){
                    // dp 배열 최신화
                    // ny,nx 위치에서 판다가 생존할 수 있는 시간+1과 현재값 중의 최댓값을 저장
                    dp[y][x] = Math.max(dp[y][x], dfs(ny,nx)+1);
                }
            }

            return dp[y][x];
        }
    }

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());

        for(int i=0;i<n;i++){
            StringTokenizer st = new StringTokenizer(br.readLine());
            for(int j=0;j<n;j++){
                req[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int ans = dfs(i,j);
                if(res < ans) res = ans;
            }
        }

        System.out.println(res);
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글