문제 풀이 날짜: 2023.08.02
포스트 작성일: 2023.08.02
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
백준 온라인 저지 2839번: 설탕 배달 (실버4)
키워드
그리디, 동적 계획법
풀이 접근법
- 그리디 또는 DP 중 택 1 하여 풀 수 있는 문제이다.
- 그리디 풀이법
- 5kg 봉지를 먼저 세면 원하는 답을 구하기 쉽지 않다. 따라서 3kg을 먼저 고려한다.
- 5kg을 먼저 빼지 않고, 3kg씩 계속 빼다가 5의 배수가 된다면 그 몫을 누적하고 종료하면 된다.
- 그렇게 하지 않으면 3kg으로만 묶이는 경우의 수를 빠트리게 된다. (예: 9kg을 3kg 3봉으로 나타냄)
- DP 풀이법
- 3의 배수, 5의 배수, 둘 다 아닌 경우로 나누어서 DP값을 갱신해간다.
- 3의 배수도 5의 배수도 아닌 경우를 누락하지 않도록 주의한다. 이 경우는 3kg과 5kg 봉지를 혼합한 형태로 나타낼 수 있기 때문이다.
- 3kg으로 묶었을 때보다 5kg으로 묶었을 때가 훨씬 개수가 적은 경우가 생길 수도 있다. 그렇기 때문에 Math.min()으로 계속 최솟값을 갱신해주어야 한다.
- 그 외
- 문제에서 주어진 3, 5kg이 모두 소수이므로 소수의 특성을 이용해서 풀 수도 있다. 이 경우 O(1) 시간만에 해결 가능하다.
코드
1. 그리디로 푸는 경우
import java.io.*;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int result = 0;
while(N >= 0) {
if(N % 5 == 0) {
result += N / 5;
System.out.println(result);
return;
}
N = N - 3;
result += 1;
}
System.out.println(-1);
}
}
2. DP로 푸는 경우
import java.io.*;
import java.util.Arrays;
public class Main {
private static int MAX = Integer.MAX_VALUE;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] DP = new int[N + 1];
Arrays.fill(DP, MAX);
DP[3] = 1;
if(N >= 5) {
DP[5] = 1;
}
for(int i = 6; i <= N ; i++) {
if(i % 3 == 0) {
DP[i] = Math.min(DP[i - 3] + 1, DP[i]);
}
if(i % 5 == 0) {
DP[i] = Math.min(DP[i - 5] + 1, DP[i]);
}
if(i % 3 != 0 && i % 5 != 0) {
if(DP[i - 3] != MAX || DP[i - 5] != MAX) {
DP[i] = Math.min(DP[i - 3], DP[i - 5]) + 1;
}
}
}
if(DP[N] == MAX) {
System.out.println(-1);
return;
}
System.out.println(DP[N]);
}
}
다양한 풀이가 가능한 문제이다. 문제에서 주어진 특정 매직 넘버들의 특징을 관찰하고 응용한다면 더욱 빠른 풀이를 구상할 수 있었다. 사용자 입력이 아닌 매직 넘버가 주어지는 문제의 경우 그 특성을 적극 활용하는 것이 좋겠다.
git 링크
(git 링크 첨부)
'Study > Problem Solving' 카테고리의 다른 글
| [백준 / Java] 12891번: DNA 비밀번호 (실버2) (0) | 2023.08.03 |
|---|---|
| [백준 / Java] 2961번: 도영이가 만든 맛있는 음식 (실버2) (0) | 2023.08.03 |
| [백준 / Java] 1244번: 스위치 켜고 끄기 (실버4) (0) | 2023.08.01 |
| [SWEA / Java] 1210번: Ladder1 (D4) (0) | 2023.08.01 |
| [백준 / Java] 10799번: 쇠막대기 (실버2) (0) | 2023.07.27 |