2294번 동전 2

서재혁·2022년 8월 15일
0

DP

목록 보기
4/6

문제

n가지 종류의 동전이 있다. 이 동전들을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그러면서 동전의 개수가 최소가 되도록 하려고 한다. 각각의 동전은 몇 개라도 사용할 수 있다.

사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.

입력

첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주어질 수도 있다.

출력

첫째 줄에 사용한 동전의 최소 개수를 출력한다. 불가능한 경우에는 -1을 출력한다.

코드

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int N, money;
vector<int> vi;
int mp[10001] = { 0, };

void solve()
{
	cin >> N >> money;
	int num;
	for (int i = 0; i < N; i++)
	{
		cin >> num;
		vi.push_back(num);
	}
	mp[0] = 0;
	for (int i = 1; i < 10001; i++)
		mp[i] = 100000;
	for (int i = 0; i < N; i++)
	{
		for (int j = vi[i]; j <= money; j++)
		{
			if(mp[j] > mp[j - vi[i]] + 1)
				mp[j] = mp[j - vi[i]] + 1;
		}
	}
	if (mp[money] != 100000)
		cout << mp[money];
	else
		cout << -1;
}

int main(void)
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	solve();
	return 0;
}

풀이

동전 1과 비슷하게 생각하면 좋다. 다만 경우의 수를 만드는 것이 아니라 동전의 갯수의 최소값을 구하는 것이다.

우선 동일하게 1원짜리 동전으로는 모든 금액을 만들 수 있다.
금액 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
동전1원 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

5원짜리 동전이 사용되기 시작하면
금액 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
동전1원 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
동전5원 0 1 2 3 4 1 2 3 4 5 2 3 4 5 6

해당 동전과 동일한 금액부터 동전의 개수가 다르게 적용되어야 하며 정확히 dp[i-5] + 1의 형태로 진행된다는 것을 알 수 있다.

이를 이용하되 동전의 개수가 현재보다 더 적을 때만 새로 입력해주어야 한다.

연관 : DP

profile
조금만 더

0개의 댓글