문제
접근 방식
이전 동전 문제처럼 k원을 만드는 모든 경우의 수를 구하는 것이 아니라
가장 적은 수의 동전을 사용해 k원을 만들 수 있는 경우를 구해야 한다.
5원, 1원, 12원 총 3개의 동전으로 15원을 만들어야 할 때
5원으로 15원을 만들 수 있는 경우를 먼저 생각해 보자
1원을 만드는 경우 : X
2원을 만드는 경우 : X
3원을 만드는 경우 : X
4원을 만드는 경우 : X
5원을 만드는 경우 : 1
6원을 만드는 경우 : X
7원을 만드는 경우 : X
8원을 만드는 경우 : X
9원을 만드는 경우 : X
10원을 만드는 경우 : 2
11원을 만드는 경우 : X
12원을 만드는 경우 : X
13원을 만드는 경우 : X
14원을 만드는 경우 : X
15원을 만드는 경우 : 3
위와 같이 5원 동전은 5원 이상의 값부터 사용할 수 있으니 자기 자신부터 1로 시작할 것이다.
N원을 만드는 경우는 (N-5)원에 5원 동전을 하나 더 사용한 것이니 DP[N-5] + 1이 되고
10원을 만드는 경우는 DP[5] + 1인 2, 15원을 만드는 경우는 DP[10] + 1인 3이 되는 것이다.
나머지 금액들은 5원만으로는 만들 수 없는 금액이니 DP[6-5]나 DP[7-5]처럼 0인 경우는 건너뛰면 된다.
이제 1원까지 사용한 경우를 계산해 보겠다.
1원을 만드는 경우 : 1
2원을 만드는 경우 : 2
3원을 만드는 경우 : 3
4원을 만드는 경우 : 4
5원을 만드는 경우 : 1 < 5
6원을 만드는 경우 : 2
7원을 만드는 경우 : 3
8원을 만드는 경우 : 4
9원을 만드는 경우 : 5
10원을 만드는 경우 : 2
11원을 만드는 경우 : 3
12원을 만드는 경우 : 4
13원을 만드는 경우 : 5
14원을 만드는 경우 : 6
15원을 만드는 경우 : 3
1 ~ 4원은 당연히 값만큼의 동전수가 사용될 것이고 DP[5]를 채우는 경우를 살펴보면
기존에 5원짜리 동전 하나만 사용하는 경우가 1원짜리 동전 5개를 사용하는 것보다 효율적이니
둘 중 더 작은 값으로 채워주면 된다.
12원 동전까지 사용하는 경우도 살펴보자
1원을 만드는 경우 : 1
2원을 만드는 경우 : 2
3원을 만드는 경우 : 3
4원을 만드는 경우 : 4
5원을 만드는 경우 : 1
6원을 만드는 경우 : 2
7원을 만드는 경우 : 3
8원을 만드는 경우 : 4
9원을 만드는 경우 : 5
10원을 만드는 경우 : 2
11원을 만드는 경우 : 3
12원을 만드는 경우 : 4 > 1
13원을 만드는 경우 : 2
14원을 만드는 경우 : 3
15원을 만드는 경우 : 3 < 4
12원 동전도 마찬가지로 12원부터 DP 테이블을 더 작은 값으로 갱신해 주면 된다.
사소한 걸 놓쳐서 여러 번 틀렸던 문제인데
DP 배열이 비어있는 경우에는 초기값인 0으로 설정되어 있기 때문에
항상 비교하면 0이 제일 작아 테이블이 정상적으로 채워지지 않는다.
배열을 생성하고 테이블을 채우기 전에 큰 값으로 초기화해주거나
테이블을 채우면서 0인 경우는 비교 없이 채우게 분기를 만들어 줘야 한다.
풀이
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int[] dp = new int[100001];
boolean[] isUsed = new boolean[100001];
for (int i = 0; i < n; i++) {
int coin = Integer.parseInt(br.readLine());
if (isUsed[coin]) continue;
isUsed[coin] = true;
dp[coin] = 1;
for (int j = coin + 1; j <= k; j++) {
if (dp[j - coin] == 0) continue;
if(dp[j] != 0) dp[j] = Math.min(dp[j], dp[j - coin] + 1);
else dp[j] = dp[j - coin] + 1;
}
}
System.out.println(dp[k] != 0 ? dp[k] : -1);
}
}
'Java > Algorithms' 카테고리의 다른 글
[백준] 10942번 : 팰린드롬? (0) | 2024.03.18 |
---|---|
[백준] 1915번 : 가장 큰 정사각형 (1) | 2024.03.17 |
[백준] 9084번 : 동전 (0) | 2024.03.16 |
[백준] 9657번 : 돌 게임 3 (1) | 2024.03.13 |
[백준] 4883번 : 삼각 그래프 (4) | 2024.03.11 |