🔗 문제 링크
A도둑과 B도둑이 팀을 이루어 모든 물건을 훔치려고 합니다. 하지만 두 도둑 중 누구도 경찰에 붙잡히지 않도록 흔적을 최소화해야 합니다.
info[i][0]
개의 A의 흔적이 남습니다.info[i][1]
개의 B의 흔적이 남습니다.접근법:
1. 내림차순 정렬: A도둑의 흔적이 큰 순서
로 정렬하되, 같으면 B의 흔적이 작은 순서
로 정렬합니다.
2. 각 물건에 대해:
private int descFirstAscSecond(int[][] info, int n, int m) {
int answer = 0;
Arrays.sort(info, (o1, o2) -> {
if (o1[0] == o2[0]) return o1[1] - o2[1];
return -(o1[0] - o2[0]);
});
for (int[] item : info) {
if (m - item[1] > 0) m -= item[1];
else {
if (n - item[0] > 0) {
n -= item[0];
answer += item[0];
} else return -1;
}
}
return answer;
}
접근법:
1. 첫 번째는 내림차순 정렬을 사용
2. 두 번째는 오름차순 정렬을 사용
3. 두 결과 중 더 작은 값을 선택
public int solution(int[][] info, int n, int m) {
int answer1 = descFirstAscSecond(info, n, m);
int answer2 = ascFirstAscSecond(info, n, m);
if (answer1 == -1) return answer2;
if (answer2 == -1) return answer1;
return Math.min(answer1, answer2);
}
private int ascFirstAscSecond(int[][] info, int n, int m) {
int answer = 0;
Arrays.sort(info, (o1, o2) -> {
if (o1[0] == o2[0]) return o1[1] - o2[1];
return o1[0] - o2[0];
});
for (int[] item : info) {
if (m - item[1] > 0) m -= item[1];
else {
if (n - item[0] > 0) {
n -= item[0];
answer += item[0];
} else return -1;
}
}
return answer;
}
접근법:
dp[i][b]
: i번째 물건까지 고려했을 때, B의 흔적이 b일 때, A의 최소 흔적 합초기화:
dp[0][0] = 0
(시작 시 흔적 없음)n
으로 초기화 (A도둑이 최대로 남길 수 있는 흔적)점화식:
dp[i][b] = min(dp[i][b], dp[i-1][b] + A의 흔적)
dp[i][b + B의 흔적] = min(dp[i][b + B의 흔적], dp[i-1][b])
최종값:
dp[info.length][b]
중에서 b < m
인 경우의 최소값을 반환b >= m
이면 -1
을 반환class Solution {
int[][] dp;
public int solution(int[][] info, int n, int m) {
dp = new int[info.length + 1][m];
// 초기화
for (int i = 1; i <= info.length; i++) {
Arrays.fill(dp[i], n);
}
dp[0][0] = 0;
// DP 수행
for (int i = 1; i <= info.length; i++) {
int a = info[i - 1][0];
int b = info[i - 1][1];
for (int j = 0; j < m; j++) {
// A도둑이 물건을 훔치는 경우
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + a);
// B도둑이 물건을 훔치는 경우
if (j + b < m)
dp[i][j + b] = Math.min(dp[i][j + b], dp[i - 1][j]);
}
}
// 정답 반환
int answer = n;
for (int j = 0; j < m; j++) {
answer = Math.min(answer, dp[info.length][j]);
}
return answer >= n ? -1 : answer;
}
}