baekjoon
[백준]2294 동전2 (수정 + 최적화)
윤만석
2022. 12. 28. 14:46
문제
n가지 종류의 동전이 있다. 이 동전들을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그러면서 동전의 개수가 최소가 되도록 하려고 한다. 각각의 동전은 몇 개라도 사용할 수 있다.
사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.
입력
첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주어질 수도 있다.
출력
첫째 줄에 사용한 동전의 최소 개수를 출력한다. 불가능한 경우에는 -1을 출력한다.
골드5 DP문제입니다.
배열 arr[i][j]는 i번째 동전까지 사용해서 j원을 만들 수 있는 최소 동전 개수입니다.
#include<bits/stdc++.h>
using namespace std;
int arr[101][10001];
vector<int>coins;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
memset(arr, -1, sizeof(arr));
int n, k, x;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> x;
coins.push_back(x);
}
sort(coins.begin(), coins.end());
coins.erase(unique(coins.begin(), coins.end()), coins.end());
for (int i = 0; i < coins.size(); i++) {
if (i == 0) {
for (int j = 1; j <= k; j++) {
j % coins[i] == 0 ? arr[i][j] = j / coins[i] : arr[i][j] = -1;
}
}
else {
for (int j = 1; j <= k; j++) {
if (j % coins[i] == 0)
arr[i][j] = j / coins[i];
else {
int temp = INT_MAX;
for (int k = 0; k <= j / coins[i]; k++) {
if (arr[i - 1][j - k* coins[i]] != -1)
temp = min(temp, k + arr[i - 1][j-k*coins[i]]);
}
if (temp == INT_MAX)
arr[i][j] = arr[i - 1][j];
else
arr[i][j] = temp;
}
}
}
}
cout << arr[coins.size() - 1][k];
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
2022-12-28
#include<iostream>
#define INTMAX 1000001
using namespace std;
int dp[10001], n, k, x;
int main() {
cin >> n >> k;
for (int i = 1; i <= k; i++)
dp[i] = INTMAX;
while (n--) {
cin >> x;
for (int i = x; i <= k; i++)
dp[i] = min(dp[i], dp[i-x] + 1);
}
dp[k] == INTMAX ? cout << -1 : cout << dp[k];
}
dp[i]는 동전 x까지 사용했을때, 최소 동전입니다. 동전x를 하나 사용했을때, dp[i-x]+1와 기존값 dp[i]를 비교해 작은 값을 저장합니다.