https://www.acmicpc.net/problem/2294
2294번: 동전 2
첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주
www.acmicpc.net

풀이 :
n 가지 동전으로 합이 k원이 되는 동전의 최소갯수를 구하는 문제
비슷한 문제로는 유명한 배낭문제랑 비슷하다.
coins배열 : n개의 동전 종류 1원부터 시작하기위해 0번인덱스는 0으로두고 1부터 n까지 동전 설정
dp 배열 : dp[n] = 가치가 n원일 때 동전의 최소 갯수
예를 들어 설명하면 동전이 n원일때(coin[] 에서 가져오면 됨) 가치가 k면 k-n원의 최소 갯수를 이용해서 구하면된다
input :
2 6
2
4
일 때
(초기 dp배열은 나올 수 있는 최대값인 10001로 설정해둔 상태, 0원을 만들 수 없기 때문에 dp[0]=0으로 초기 설정)
코드와 상관없이 상식적으로 채워보면 2원일 때 dp배열 상태가 이렇게 됨
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
2원 | 0 | max | 1 | max | 2 | max | 3 |
4원 |
4원의 경우 4보다 작은 경우에는 영향을 주지 않는다
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
2원 | 0 | max | 1 | max | 2 | max | 3 |
4원 | 1 | max | 2 |
가치가 4일때 4원짜리 하나
6일때는 4원짜리 하나 + 2원짜리 하나
위와 같은 과정으로 점화식을 세워보면
dp[가치 - 현재 동전의 값]+1인 식을 세울 수 있다.
위 점화식을 말로 풀어 보면 가치가 6일때 4원을 하나 쓰면 2원이 남으므로 dp[2]인 경우에 +1(4원하나 뽑았으니까)하는 거라고 생각하면 된다.
코드 :
#include <iostream> #include <algorithm> #define MAX 10001 using namespace std; int n, k; int dp[10001]; int coins[101]; int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); dp[0] = 0; cin >> n >> k; for (int i = 1; i <= n; i++) cin >> coins[i]; for (int i = 1; i <= k; i++) dp[i] = MAX; for (int i = 1; i <= n; i++) { for (int j = coins[i]; j <= k; j++) { dp[j] = min(dp[j], dp[j - coins[i]]+1); } } int answer = dp[k] == MAX ? -1 : dp[k]; cout << answer << endl; }
'baekjoon' 카테고리의 다른 글
[DFS]백준 2644 촌수계산 C++ (0) | 2022.02.06 |
---|---|
[DP] 백준 1699 제곱수의 합 C++ (0) | 2022.01.26 |
[문자열] 백준 5430 AC C++ (0) | 2022.01.24 |
[그리디] 백준 4796 캠핑 C++ (0) | 2021.09.02 |
[DP] 백준 2225 합분해 C++ (0) | 2021.09.01 |
댓글