• 티스토리 홈
  • 프로필사진
    유니얼
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
유니얼
  • 프로필사진
    유니얼
    • 분류 전체보기 (295)
      • Unity (17)
        • 게임 개발 (5)
      • Unreal (24)
        • 게임 개발 (20)
      • DirectX (36)
      • 코딩테스트 (91)
        • 프로그래머스 (25)
        • 백준 (66)
      • Google Workspace (1)
      • Programing (102)
        • C# (68)
        • C++ (24)
        • JavaScript (10)
      • 게임 서버 프로그래밍 (17)
      • Web (6)
        • 슈퍼코딩 (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
    등록된 댓글이 없습니다.
  • 최근 공지
    등록된 공지가 없습니다.
# Home
# 공지사항
#
# 태그
# 검색결과
# 방명록
  • [99클럽/코딩테스트 챌린지/C++] 완전 탐색과 원복 (피로도 문제)
    2024년 11월 18일
    • 유니얼
    • 작성자
    • 2024.11.18.:56
    728x90

    문제 링크 : 

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

     

    프로그래머스

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

    programmers.co.kr

    문제 요약

    이 문제는 주어진 현재 피로도 kkk와 여러 던전의 "최소 필요 피로도"와 "소모 피로도"를 활용해, 최대 몇 개의 던전을 탐험할 수 있는지를 계산하는 문제입니다. 던전을 탐험하기 위해서는 다음 조건을 만족해야 합니다:

    1. 현재 남은 피로도가 "최소 필요 피로도" 이상이어야 탐험이 가능합니다.
    2. 탐험한 던전 수를 최대화해야 합니다.

    문제를 해결하기 위해 모든 가능한 탐험 경로를 탐색하고, 상태를 복구(원복)하며 탐색을 진행해야 합니다.

    접근법

    완전 탐색

    1, 모든 가능한 던전 탐험 순서를 탐색해야 하므로, 완전 탐색(Brute Force) 방식으로 문제를 해결합니다.

    2, 각 던전마다 현재 남은 피로도가 탐험 가능하다면:

    • 해당 던전을 탐험하고 다음 단계로 이동합니다.
    • 탐색이 끝난 후 상태를 복구(원복)하여 다른 경로를 탐험합니다.

    3, 이를 통해 최적의 탐험 수를 계산할 수 있습니다.

    원복의 중요성

    1, 탐험 과정에서 상태를 변경한 후, 다른 경로를 탐색하기 위해 이전 상태로 복구하는 작업을 원복(Backtracking)이라고 합니다.

    2, 원복이 없으면, 탐색이 중첩되거나 중복 방문이 발생해 잘못된 결과를 초래할 수 있습니다.

    3, 이 문제에서는:

    1. 남은 피로도 (remain)
    2. 탐험한 던전 수 (counts)
    3. 방문 여부 (visited)

    이 세 가지 상태를 원복해야 정확한 결과를 얻을 수 있습니다.

     

    코드

    #include <string>
    #include <vector>
    
    using namespace std;
    
    int remain = 80; // 현재 남은 피로도
    int counts = 0;  // 탐험한 던전 수
    int answer = -1; // 탐험 가능한 최대 던전 수
    vector<int> visited; // 방문 여부 추적
    
    // 모든 던전을 탐색하는 함수
    void findDungeon(vector<vector<int>>& dungeons) {
        for (int i = 0; i < dungeons.size(); i++) {
            // 최소 필요 피로도를 만족하지 못하거나 이미 방문한 던전은 스킵
            if (dungeons[i][0] > remain) continue;
            if (visited[i]) continue;
    
            // 상태 변경: 던전 탐험
            remain -= dungeons[i][1]; // 피로도 소모
            counts++; // 탐험한 던전 수 증가
            visited[i]++; // 던전 방문 처리
    
            // 최대 탐험 던전 수 갱신
            answer = max(answer, counts);
    
            // 다음 단계 탐색
            findDungeon(dungeons);
    
            // 원복(Backtracking): 상태 복구
            remain += dungeons[i][1]; // 소모된 피로도 복구
            visited[i]--; // 방문 상태 초기화
            counts--; // 탐험 던전 수 감소
        }
    }
    
    int solution(int k, vector<vector<int>> dungeons) {
        remain = k; // 초기 피로도 설정
        answer = -1; // 최대 탐험 던전 수 초기화
    
    	for(int i = 0; i < dungeons.size(); i++)
    	{
    		// 현재 i 번쨰 던전의 필요 피로도가 현재 플레이어의 피로도 보다 크다면
    		// 다음 던전으로 이동
            if (dungeons[i][0] > k) continue; // 탐험 불가능한 던전 스킵
    
            visited = vector<int>(dungeons.size()); // 방문 여부 초기화
            remain = k; // 남은 피로도 초기화
            counts = 0; // 탐험 던전 수 초기화
    
            findDungeon(dungeons); // 탐색 시작
    	}
    
        return answer;
    }

    문제 해결 과정

    1. 완전 탐색 구현

    • 모든 던전을 탐험할 수 있도록 반복문과 재귀를 사용해 경로를 탐색합니다.
    • 각 단계에서 탐험 가능한 던전인지 확인하고, 가능하다면 탐험 후 다음 단계로 이동합니다.

    2. 상태 원복 구현

    • 탐험 후 다른 경로를 탐색하기 위해 상태를 복구해야 합니다.
    • 원복 작업:
      • 탐험 중 소모된 remain(피로도)을 복구합니다.
      • 탐험 던전 수 counts를 감소시킵니다.
      • 방문 여부 visited를 초기 상태로 복구합니다.

    3. 최대값 갱신

    • 탐험 경로를 진행할 때마다 answer 값을 갱신합니다.
    • 탐색이 종료되면 최적의 결과가 answer에 저장됩니다.

    배운 점

    1, 완전 탐색과 원복의 역할

    • 완전 탐색은 모든 경로를 탐색하며 최적의 결과를 도출하기 위해 필수적입니다.
    • 탐색 과정에서의 상태 원복(Backtracking)은 탐색 경로를 올바르게 유지하는 핵심 요소입니다.

    2, 재귀 함수 내 상태 관리

    • 재귀 호출은 현재 상태를 변경하므로, 호출 후에는 반드시 상태를 복구해야 합니다.
    • 원복을 통해 다른 경로 탐색에 영향을 주지 않도록 하는 것이 중요합니다.

    3, 방문 여부와 조건 처리

    • 방문 여부(visited)를 효율적으로 관리하지 않으면, 중복 방문이나 잘못된 경로 탐색이 발생할 수 있습니다.
    • 각 던전의 조건을 정확히 체크하고, 조건에 맞지 않는 경우 탐색을 건너뛰는 것이 필요합니다.

    결론

    이 문제를 통해 완전 탐색과 Backtracking(원복)의 중요성을 다시금 깨달을 수 있었습니다. 완전 탐색은 모든 경로를 탐색하며 최적의 결과를 보장하고, Backtracking은 각 경로를 독립적으로 관리하여 정확한 계산을 가능하게 합니다.

    앞으로도 복잡한 탐색 문제를 해결할 때, 원복과 상태 관리를 철저히 하여 최적의 결과를 얻도록 하겠습니다. 

    반응형
    다음글
    다음 글이 없습니다.
    이전글
    이전 글이 없습니다.
    댓글
조회된 결과가 없습니다.
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바