
Part of series: PS
1398 BOJ
문제
접근
다이내믹 프로그래밍으로 해결하였다.
동전의 개수가 무제한인 점과, 1XXX원 혹은 25XXX원 으로 구성되어 있다는 점에서, 주어진 금액을 두 자릿수 단위로 쪼개 계산하면 된다는 점을 알 수 있었다. 123456원이 주어지면 12, 34, 56 으로 쪼개 계산하는 것이다. 두 자릿수의 경우 1원, 10원, 25원짜리 동전으로 표현할 수 있다. 두 자릿수를 넘어가는 세 자릿수 등의 경우에는 다시 두 자릿수로 환원해 계산하는 것이 최적의 경우이다.
따라서 두 자릿수로 쪼개 각각의 경우에 소비되는 1원, 10원, 25원짜리 동전의 개수를 구해 더하면 된다. 100 미만의 가격들에 대하여 1원, 10원, 25원짜리 동전들로 구성할 때 소비되는 최소의 동전 개수를 dp 배열에 저장하여 재활용하였다.
코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef const ll cll;
typedef queue<ll> qll;
typedef queue<pll> qpll;
typedef priority_queue<ll> pqll;
typedef priority_queue<pll> pqpll;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<vll> vvll;
typedef vector<vpll> vvpll;
#define FOR1(a, A) for (ll a = 0; a < A; ++a)
#define FOR2(a, b, A, B) \
for (ll a = 0; a < A; ++a) \
for (ll b = 0; b < B; ++b)
const ll INF = 100, coins[3] = {25, 10, 1};
vll dp(100, INF);
// 1, 10, 25;
ll find(ll price) {
if (dp[price] != INF) {
return dp[price];
} else if (price == 0) {
return dp[price] = 0;
}
for (auto coin : coins) {
if (price >= coin) {
dp[price] = min(dp[price], find(price - coin) + 1);
}
}
return dp[price];
}
ll solve(ll price) {
ll result = 0;
while (price) {
result += find(price % 100);
price /= 100;
}
return result;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
ll t;
cin >> t;
while (t--) {
ll price;
cin >> price;
cout << solve(price) << "\n";
}
return 0;
}