메모리: 88.7 MB, 시간: 0.38 ms
코딩테스트 연습 > 2025 프로그래머스 코드챌린지 2차 예선
정확성: 100.0
합계: 100.0 / 100.0
2025년 03월 04일 13:46:06
A도둑과 B도둑이 팀을 이루어 모든 물건을 훔치려고 합니다. 단, 각 도둑이 물건을 훔칠 때 남기는 흔적이 누적되면 경찰에 붙잡히기 때문에, 두 도둑 중 누구도 경찰에 붙잡히지 않도록 흔적을 최소화해야 합니다.
물건을 훔칠 때 조건은 아래와 같습니다.
info[i][0]개의 A에 대한 흔적을 남깁니다.info[i][1]개의 B에 대한 흔적을 남깁니다.경찰에 붙잡히는 조건은 아래와 같습니다.
n개 이상이면 경찰에 붙잡힙니다.m개 이상이면 경찰에 붙잡힙니다.각 물건을 훔칠 때 생기는 흔적에 대한 정보를 담은 2차원 정수 배열 info, A도둑이 경찰에 붙잡히는 최소 흔적 개수를 나타내는 정수 n, B도둑이 경찰에 붙잡히는 최소 흔적 개수를 나타내는 정수 m이 매개변수로 주어집니다. 두 도둑 모두 경찰에 붙잡히지 않도록 모든 물건을 훔쳤을 때, A도둑이 남긴 흔적의 누적 개수의 최솟값을 return 하도록 solution 함수를 완성해 주세요. 만약 어떠한 방법으로도 두 도둑 모두 경찰에 붙잡히지 않게 할 수 없다면 -1을 return해 주세요.
info의 길이 ≤ 40
info[i]는 물건 i를 훔칠 때 생기는 흔적의 개수를 나타내며, [A에 대한 흔적 개수, B에 대한 흔적 개수]의 형태입니다.흔적 개수 ≤ 3n ≤ 120m ≤ 120아래는 테스트 케이스 구성을 나타냅니다. 각 그룹 내의 테스트 케이스를 모두 통과하면 해당 그룹에 할당된 점수를 획득할 수 있습니다.
| 그룹 | 총점 | 테스트 케이스 그룹 설명 |
|---|---|---|
| #1 | 15% | info[i][1] = 1 |
| #2 | 40% | info의 길이 ≤ 20 |
| #3 | 45% | 추가 제한 사항 없음 |
| 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 |
입출력 예 #1
첫 번째와 세 번째 물건을 B도둑이 훔치고 두 번째 물건을 A도둑이 훔치면, A도둑에 대한 흔적은 총 2개이고 B도둑에 대한 흔적은 총 3개입니다. 목표를 달성하면서 A도둑에 대한 흔적 개수를 2보다 더 낮게 만들 수 없습니다.
따라서 2를 return 해야 합니다.
입출력 예 #2
B도둑이 모든 물건을 훔쳐도 B의 흔적이 7개 이상 쌓이지 않습니다.
따라서 A도둑의 흔적은 최소 0이 되며, 0을 return 해야 합니다.
입출력 예 #3
B도둑이 한 번이라도 물건을 훔치면 B의 흔적이 최소 1개 이상 남습니다. 따라서 모든 물건을 A도둑이 훔쳐야 하며, 이 경우에도 A의 흔적은 7개 미만입니다.
따라서, A도둑이 모든 물건을 훔칠 때의 흔적 개수 6을 return 해야 합니다.
입출력 예 #4
어떤 방법으로도 두 도둑 모두 경찰에 붙잡히지 않고 모든 물건을 훔칠 수 없습니다.
따라서 -1을 return 해야 합니다.
출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
dp[i][j] = Math.min(dp[i-1][j], dp[i-1][j-(B가 남기는 흔적)] - (A가 남기는 흔적)import java.lang.*;
class Solution {
public int solution(int[][] info, int n, int m) {
int cnt = info.length;
// 행 인덱스: 물건의 번호, 열 인덱스: B가 남길 수 있는 흔적의 한계
// value: A가 남길 수 있는 최소의 흔적
int[][] dp = new int[cnt][m];
// 모든 물건을 A가 훔치는 경우의 값
int max = 0;
for (int i = 0; i < cnt; i++) max += info[i][0];
// 0번 인덱스 물건 초기화
// B가 물건을 훔칠 수 있는 부분부터 value에서 A의 흔적 값을 지워 최소값 갱신
for (int j = 0;j < m; j++) {
if (j < info[0][1]) dp[0][j] = max;
else dp[0][j] = max - info[0][0];
}
for (int i = 1; i < cnt; i++) {
for (int j = 0; j < m; j++) {
if (j < info[i][1]) dp[i][j] = dp[i-1][j];
else dp[i][j] = Math.min(dp[i-1][j], dp[i-1][j-info[i][1]] - info[i][0]);
}
}
// 최종 값이 n 이상일 경우, 가능한 경우가 없다는 뜻
if (dp[cnt - 1][m - 1] >= n) return -1;
return dp[cnt - 1][m-1];
}
}