문제:
n가지 종류의 동전이 있다. 이 동전들을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그러면서 동전의 개수가 최소가 되도록 하려고 한다. 각각의 동전은 몇 개라도 사용할 수 있다.
사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.
입력:
첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주어질 수도 있다.
출력:
첫째 줄에 사용한 동전의 최소 개수를 출력한다. 불가능한 경우에는 -1을 출력한다.
풀이방법:
www.acmicpc.net/problem/2293 의 동전 1 문제를 응용해서 풀면 된다. 이 문제에서는 k원을 만드는 경우의 수를 구하는 문제였지만, 이 문제에서는 최솟값을 구해야 한다. 따라서 동전의 가치가 최대 100,000원이므로 초기값으로 100,001원(0원은 0으로 초기화 한다.) 으로 설정하고, 작은 동전부터 사용해서 각 p원을 만들 수 있는 최소 갯수를 구하도록 한다.
이 문제의 예시로 생각하면 다음과 같다. (1,5,12)원이 있을 때, 1원으로 15원을 만드는 방법은 다음과 같이 비교할 것이다.
위 표는 다음 두 조건을 비교하면서 채워나갔다. 1원을 만드는 경우로 예시를 든다.
1. 현재 값을 그대로 사용한다. dp[1]
2. 0원에서 1원을 더해서 사용한다. dp[1-1]+1
3. 1과 2중 더 작은 값을 사용한다. min(dp[1],dp[1-1]+1)
즉 이를 일반화 하면 다음과 같다. min(dp[n],dp[n-c]+1), n은 현재 만들고자 하는 금액, c는 현재 사용하고 있는 동전의 가치다.
5원을 사용하는 경우는 1~4원은 만드는 것이 불가능하므로 5원부터 반복한다.
12원을 사용하는 경우는 1~11원은 만드는 것이 불가능하므로 12부터 반복한다.
최종적으로는 dp[k]원이 초기화한 값에서 변경이 되었다면 dp[k]를 출력하고, 바뀌지 않았다면 -1을 출력하도록 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
n,k = map(int,input().split())
coin = []
for _ in range(n):
coin.append(int(input()))
dp=[100001]*(k+1)
dp[0]=0
for c in coin:
for i in range(c,k+1):
dp[i]=min(dp[i],dp[i-c]+1)
if dp[k]==100001:
print(-1)
else:
print(dp[k])
|
cs |
문제링크:
'Algorithm > Python' 카테고리의 다른 글
[BOJ]1527. 금민수의 개수 (0) | 2020.12.22 |
---|---|
[BOJ]7453. 합이 0인 네 정수 (0) | 2020.12.10 |
[BOJ]11060. 점프 점프 (0) | 2020.12.03 |
[BOJ]10835. 카드게임 (0) | 2020.12.01 |
[BOJ]1747. 소수&팰린드롬 (0) | 2020.11.26 |