https://www.acmicpc.net/problem/2294
풀이
첫번째 줄에 n,k를 입력한다. n은 서로 다른 값의 동전의 종류이고 그 동전들을 적당히 이용해서 그 가치의 합을 k로 만들어야할때, 동전의 개수가 최소가 될때를 구해야한다.
단, 불가능한 경우에는 -1을 출력하기로 한다.
arr[101]을 0으로 초기화해주고
dp[100001] 을 memset(dp, -1, sizeof(dp));를 이용해서 -1로 초기화 해주기로 한다.
dp[0]은 0 으로 초기화
동전1 문제의 풀이법을 변형해서 dp[i] = dp[i - arr[j]] + 1; 을 사용하여 동전이 사용될 때마다 +1 을 누적하여 dp에 담기로 한다.
if( i >= arr[j] && dp[i - arr[j]] != -1)의 조건을 주어서 arr[j] 동전이 i의 값을 넘지 않고 dp[i - arr[j]]이 이전의 동전들의 값으로 만들 수 있는 경우만 생각하면 된다.
하지만 dp[i] == -1 인 경우는 dp[i]가 처음으로 -1에서 값을 가지는 순간이므로 min함수로 비교를 하지않고 바로 dp[i] = dp[i - arr[j]] +1; 이 된다. 이 다음부터는
dp[i] = min(dp[i], dp[i - arr[j]] + 1);로 매번 비교를 해주어야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define min(a,b) a<b ? a:b int main() { int n, k; int arr[101] = { 0 }; int dp[10001]; memset(dp , -1, sizeof(dp)); dp[0] = 0; scanf("%d %d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &arr[i]); } for (int i = 1; i <= k; i++) { for (int j = 1; j <= n; j++) { if (i >= arr[j] && dp[i - arr[j]] != -1) { if (dp[i] == -1) dp[i] = dp[i - arr[j]] + 1; else dp[i] = min(dp[i], dp[i - arr[j]] + 1); } } } printf("%d\n", dp[k]); return 0; } | cs |
'알고리즘' 카테고리의 다른 글
(1699)(DP) 백준 제곱수의 합 (0) | 2018.08.04 |
---|---|
(11048)(DP) 백준 이동하기 (0) | 2018.08.01 |
(11057)(DP) 백준 오르막 수 (0) | 2018.07.30 |
(2167)(DP) 백준 2차원 배열의 합 (0) | 2018.07.30 |
(9461)(DP) 파도반 수열 (0) | 2018.07.30 |