honey_pot
[DP] 8 - 5 효율적인 화폐 구성 본문
N가지 종류의 화폐가 있다. 이 화폐들의 개수를 최소한으로 이용해서 그 가치의 합이 M원이 되도록 한다. 각 화폐는 몇 개라도 사용할 수 있으며, 사용한 화폐의 구성은 같지만 순서만 다른 것은 같은 경우로 구분한다. 예를 들어 2원, 3원 단위의 화폐가 있을 때는 15원을 만들기 위해 3원을 5개 사용하는 것이 가장 최소한의 화폐 개수이다.
입력 조건
- 첫째 줄에 N,M이 주어진다. (1<=N<=100 , 1<=M<=10,000)
- 이후의 N개의 줄에는 각 화폐의 가치가 주어진다. 화폐의 가치는 10,000보다 작거나 같은 자연수이다.
출력 조건
- 첫째 줄에 경우의 수 X를 출력한다.
- 불가능할 때는 -1을 출력한다.
입력예시1
2 5
2
3
출력예시1
5
입력예시2
3 4
3
5
7
출력예시1
-1
해결 방법
적은 금액부터 큰 금액까지 확인하며 차례대로 만들 수 있는 최소한의 화폐 개수를 찾는다.
금액 i를 만들 수 있는 최소한의 화폐 개수를 a[i], 화폐의 단위를 k라고 했을 때 다음과 같은 점화식을 작성할 수 있다. a[i-k]는 금액 (i-k)를 만들 수 있는 최소한의 화폐 개수를 의미한다.
- a[i-k]를 만드는 방법이 존재하는 경우 : a[i] = min(a[i], a[i-k]+1)
- a[i-k]를 만드는 방법이 존재하지 않는 경우: a[i] = 10,001
# 정수 N, M를 입력받기
n, m = map(int,input().split())
# N개의 화폐 단위 정보를 입력받기
list = []
for i in range(n):
list.append(int(input()))
# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화
d = [10001] * (m + 1)
# 보텀업
d[0] = 0
d[min(list)] = 1
for i in range(min(list), m+1):
for money in list:
# 음수가 되면 중단한다
if i - money < 0:
break
else:
d[i] = min(d[i], d[i-money]+1) # 최솟값 갱신
if d[m] == 10001:
print(-1)
else:
print(d[m])
'이것이 코딩테스트다' 카테고리의 다른 글
[최단 경로] 9 - 1 (2)플로이드 워셜 최단 경로 알고리즘 (0) | 2021.06.19 |
---|---|
[최단 경로] 9 - 1 (1) 다익스트라 최단 경로 알고리즘 (0) | 2021.06.19 |
[DP] 8 - 4 바닥 공사 (0) | 2021.06.19 |
[DP] 8 - 3 개미 전사 (0) | 2021.06.19 |
[DP] 8 - 2 1로 만들기 (0) | 2021.06.19 |
Comments