본문 바로가기

코딩테스트/프로그래머스

완전범죄

728x90
반응형


📌 문제 설명

A도둑과 B도둑이 팀을 이루어 모든 물건을 훔치려고 합니다. 단, 각 도둑이 물건을 훔칠 때 남기는 흔적이 누적되면 경찰에 붙잡히기 때문에, 두 도둑 중 누구도 경찰에 붙잡히지 않도록 흔적을 최소화해야 합니다.


물건을 훔칠 때 조건은 아래와 같습니다.

  • 물건 i를 훔칠 때,
    • A도둑이 훔치면 info[i][0]개의 A에 대한 흔적을 남깁니다.
    • B도둑이 훔치면 info[i][1]개의 B에 대한 흔적을 남깁니다.
  • 각 물건에 대해 A도둑과 B도둑이 남기는 흔적의 개수는 1 이상 3 이하입니다. 

 

경찰에 붙잡히는 조건은 아래와 같습니다.

  • 도둑은 자신이 남긴 흔적의 누적 개수가 n개 이상이면 경찰에 붙잡힙니다.
  • B도둑은 자신이 남긴 흔적의 누적 개수가 m개 이상이면 경찰에 붙잡힙니다.

 

각 물건을 훔칠 때 생기는 흔적에 대한 정보를 담은 2차원 정수 배열 info, A도둑이 경찰에 붙잡히는 최소 흔적 개수를 나타내는 정수 n, B도둑이 경찰에 붙잡히는 최소 흔적 개수를 나타내는 정수 m이 매개변수로 주어집니다. 두 도둑 모두 경찰에 붙잡히지 않도록 모든 물건을 훔쳤을 때, A도둑이 남긴 흔적의 누적 개수의 최솟값을 return 하도록 solution 함수를 완성해 주세요. 만약 어떠한 방법으로도 두 도둑 모두 경찰에 붙잡히지 않게 할 수 없다면 -1을 return해 주세요.

 

📌 제한 사항

  • 1 ≤ info의 길이 ≤ 40
    • info[i]는 물건 i를 훔칠 때 생기는 흔적의 개수를 나타내며, [A에 대한 흔적 개수, B에 대한 흔적 개수]의 형태입니다.
    • 1 ≤ 흔적 개수 ≤ 3
  • 1 ≤ n ≤ 120
  • 1 ≤ m ≤ 120

 

📌 입출력 예

 info n m  result
[[1, 2], [2, 3], [2, 1]] 4 4 2
[[1, 2], [2, 3], [2, 1]] 1 7 0
[[3, 3], [3, 3]] 7 1 6
[[3, 3], [3, 3]] 6 1 -1

 

🔗 문제 링크

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

 

프로그래머스

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

programmers.co.kr


반응형

💡 풀이 아이디어

  • 동적 계획법

📝 최종 풀이

  • 상태 정의
    • 각 물건을 A 도둑 또는 B 도둑이 훔쳤을 때 누적 흔적을 추적해야한다.
    • dp[i][a][b]= i 번째 물건까지 고려했을 A의 누적흔적이 a이고, B의 누적흔적이 b일 때, A가 남긴 최소 누적 흔적 값
    • 초기값 dp[0][0][0] = 0은 아무 물건도 훔치지 않았을 때 두 도둑의 누적 흔적은 0, 나머지는 121로 초기화
  • 점화식
    • i+1번째 물건까지 고려했을 때 최소 A 도둑 흔적 값은, i번째 물건까지 고려했을 때의 최소 A 도둑 흔적 값에 현재 물건을 훔치면서 발생한 A 도둑의 흔적을 더한 값과 현재 저장된 값 중 더 작은 값으로 업데이트

728x90

👩‍💻 코드

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int solution(vector<vector<int>> info, int n, int m) {
    int answer = 121;
    int info_size = info.size();
    vector<vector<vector<int>>> dp(info_size + 1, vector<vector<int>>(n, vector<int>(m, 121)));
    
    dp[0][0][0] = 0;
    
    for (int i=0; i<info_size; i++){
        int a_current = info[i][0];
        int b_current = info[i][1];
        
        for (int a_index = 0; a_index < n; a_index++){
            for (int b_index = 0; b_index < m; b_index++){
                if (dp[i][a_index][b_index] == 121){
                    continue;
                }
                
                if(a_index + a_current < n){
                    dp[i+1][a_index+a_current][b_index] = min(dp[i + 1][a_index + a_current][b_index], dp[i][a_index][b_index] + a_current);
                }
                
                if (b_index + b_current < m) {
                    dp[i + 1][a_index][b_index + b_current] = min(dp[i + 1][a_index][b_index + b_current], dp[i][a_index][b_index]);
                }
            }
        }
    }
    
    for(int a_index = 0; a_index < n; a_index++){
        for(int b_index = 0; b_index < m; b_index++){
            answer = min(answer, dp[info_size][a_index][b_index]);
        }
    }
    
    return (answer == 121) ? -1 : answer;
}
728x90
반응형

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

기둥과 보 설치  (0) 2025.05.12
지게차와 크레인  (0) 2025.03.17
서버 증설 횟수  (0) 2025.03.14
비밀 코드 해독  (0) 2025.03.14
택배 상자 꺼내기  (0) 2025.03.14