쉽게 쉽게

[프로그래머스] 피로도 (DFS/백트래킹) - Java 본문

문제풀이/프로그래머스

[프로그래머스] 피로도 (DFS/백트래킹) - Java

곱마2 2025. 11. 24. 14:53
반응형

▤ 목차

    1. 문제설명

    https://school.programmers.co.kr/learn/courses/30/lessons/87946

     

    프로그래머스

    SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

    programmers.co.kr

    문제 설명
    XX게임에는 피로도 시스템(0 이상의 정수로 표현합니다)이 있으며, 일정 피로도를 사용해서 던전을 탐험할 수 있습니다. 이때, 각 던전마다 탐험을 시작하기 위해 필요한 "최소 필요 피로도"와 던전 탐험을 마쳤을 때 소모되는 "소모 피로도"가 있습니다. "최소 필요 피로도"는 해당 던전을 탐험하기 위해 가지고 있어야 하는 최소한의 피로도를 나타내며, "소모 피로도"는 던전을 탐험한 후 소모되는 피로도를 나타냅니다. 예를 들어 "최소 필요 피로도"가 80, "소모 피로도"가 20인 던전을 탐험하기 위해서는 유저의 현재 남은 피로도는 80 이상 이어야 하며, 던전을 탐험한 후에는 피로도 20이 소모됩니다.

    이 게임에는 하루에 한 번씩 탐험할 수 있는 던전이 여러개 있는데, 한 유저가 오늘 이 던전들을 최대한 많이 탐험하려 합니다. 유저의 현재 피로도 k와 각 던전별 "최소 필요 피로도", "소모 피로도"가 담긴 2차원 배열 dungeons 가 매개변수로 주어질 때, 유저가 탐험할수 있는 최대 던전 수를 return 하도록 solution 함수를 완성해주세요.

    제한사항
    k는 1 이상 5,000 이하인 자연수입니다.
    dungeons의 세로(행) 길이(즉, 던전의 개수)는 1 이상 8 이하입니다.
    dungeons의 가로(열) 길이는 2 입니다.
    dungeons의 각 행은 각 던전의 ["최소 필요 피로도", "소모 피로도"] 입니다.
    "최소 필요 피로도"는 항상 "소모 피로도"보다 크거나 같습니다.
    "최소 필요 피로도"와 "소모 피로도"는 1 이상 1,000 이하인 자연수입니다.
    서로 다른 던전의 ["최소 필요 피로도", "소모 피로도"]가 서로 같을 수 있습니다.


    입출력 예

    k dungeons  result
    80 [[80,20],[50,40],[30,10]] 3


    입출력 예 설명
    현재 피로도는 80입니다.
    만약, 첫 번째 → 두 번째 → 세 번째 던전 순서로 탐험한다면
    현재 피로도는 80이며, 첫 번째 던전을 돌기위해 필요한 "최소 필요 피로도" 또한 80이므로, 첫 번째 던전을 탐험할 수 있습니다. 첫 번째 던전의 "소모 피로도"는 20이므로, 던전을 탐험한 후 남은 피로도는 60입니다.
    남은 피로도는 60이며, 두 번째 던전을 돌기위해 필요한 "최소 필요 피로도"는 50이므로, 두 번째 던전을 탐험할 수 있습니다. 두 번째 던전의 "소모 피로도"는 40이므로, 던전을 탐험한 후 남은 피로도는 20입니다.
    남은 피로도는 20이며, 세 번째 던전을 돌기위해 필요한 "최소 필요 피로도"는 30입니다. 따라서 세 번째 던전은 탐험할 수 없습니다.
    만약, 첫 번째 → 세 번째 → 두 번째 던전 순서로 탐험한다면
    현재 피로도는 80이며, 첫 번째 던전을 돌기위해 필요한 "최소 필요 피로도" 또한 80이므로, 첫 번째 던전을 탐험할 수 있습니다. 첫 번째 던전의 "소모 피로도"는 20이므로, 던전을 탐험한 후 남은 피로도는 60입니다.
    남은 피로도는 60이며, 세 번째 던전을 돌기위해 필요한 "최소 필요 피로도"는 30이므로, 세 번째 던전을 탐험할 수 있습니다. 세 번째 던전의 "소모 피로도"는 10이므로, 던전을 탐험한 후 남은 피로도는 50입니다.
    남은 피로도는 50이며, 두 번째 던전을 돌기위해 필요한 "최소 필요 피로도"는 50이므로, 두 번째 던전을 탐험할 수 있습니다. 두 번째 던전의 "소모 피로도"는 40이므로, 던전을 탐험한 후 남은 피로도는 10입니다.
    따라서 이 경우 세 던전을 모두 탐험할 수 있으며, 유저가 탐험할 수 있는 최대 던전 수는 3입니다.

    2. 문제풀이

    나의 풀이

    class Solution {
        // 던전 탐험을 통해 얻을 수 있는 최대 횟수를 저장하는 변수
        static int maxDungeons = 0;
        
        // 던전 방문 여부를 저장하는 배열
        static boolean[] visited;
    
        public int solution(int k, int[][] dungeons) {
            // 던전의 개수
            int n = dungeons.length;
            // 방문 배열 초기화
            visited = new boolean[n];
            
            // DFS(현재 남은 피로도, 던전 배열, 현재까지 탐험한 횟수)를 시작
            dfs(k, dungeons, 0);
            
            // 탐험 가능한 최대 횟수 반환
            return maxDungeons;
        }
        
        public static void dfs(int current_health, int[][] dungeons, int count){
            // 현재까지 탐험한 횟수와 최대 횟수를 비교하여 갱신
            maxDungeons = Math.max(maxDungeons, count);
        
            for(int i =0; i<dungeons.length; i++){
                int required_health = dungeons[i][0]; //최소 피로도
                int waste_health = dungeons[i][1]; //소모 피로도
                
                if(!visited[i] && current_health >= required_health){ //던전 최초 방문, 최소 피로도보다 높을때
                    visited[i] = true; //던전 방문 처리
                    
                    // 피로도를 소모하고 탐험 횟수를 증가시켜 다음 레벨의 탐색을 진행
                    dfs(current_health - waste_health , dungeons, count + 1);
                    
                    // for 루프의 다음 반복에서 다른 던전을 먼저 탐험하는 새로운 순서를 시도하기 위해 값을 되돌림
                    visited[i] = false;
                    
                }
                
            }
            
            
        }
    }

    트리나 그래프를 탐색하는 기법 중 하나로, 시작 노드에서 자식의 노드들을 순서대로 탐색하면서 깊이를 우선으로 탐색하는 알고리즘이다.

    깊이를 우선시하여 모든 경우의 수를 탐색하기 때문에, 완전탐색 알고리즘에 속하기는 하지만, 항상 완전탐색으로 사용되지는 않는다.

    DFS는 주로 반복문을 활용하거나, 재귀문을 통하여 구현된다.

    잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다.
    반응형