[문제 링크]

 

2294번: 동전 2

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

www.acmicpc.net


https://onlytrying.tistory.com/89 동전 1의 변형 문제였다.

 

입력받은 동전의 가치를 배열 coin[n]에 저장할 때, k원을 만드는 동전의 최소 개수는 i = 1~n까지 k-coin[i]원을 만드는 최소 개수가 가장 작은 개수 + 1이다.

 

k원을 만들지 못하는 경우 -1을 출력해줘야 하기 때문에 top-down에서는 기저사례로 k가 0보다 작을 때 무한대(INF)를 반환하도록 하였고, bottom-up에서는 초기값을 무한대(INF)로 초기화하였다.


#include <iostream>
#include <cstring>
using namespace std;

const int INF = 987654321;
int n, k, coin[101], memoTop[101][10000], memoBot[10000];

inline int min(int a, int b) { return a < b ? a : b; }

int Topdown(int start, int k)
{
	if (k <= 0) return k == 0 ? 0 : INF;

	int& ret = memoTop[start][k];
	if (ret != -1) return ret;

	ret = INF;
	for (int i = start; i <= n; i++)
		ret = min(ret, Topdown(i, k - coin[i]) + 1);

	return ret;
}

int Bottomup(int k)
{
	for (int i = 1; i <= k; i++)
	{
		memoBot[i] = INF;
		for (int j = 1; j <= n; j++)
			if (i - coin[j] >= 0)
				memoBot[i] = min(memoBot[i], memoBot[i - coin[j]] + 1);
	}
	
	return memoBot[k] == INF ? -1 : memoBot[k];
}

int main(void)
{
	cin >> n >> k;

	for (int i = 1; i <= n; i++)
		cin >> coin[i];

	// top-down
	memset(memoTop, -1, sizeof(memoTop));
	int res = Topdown(1, k);
	if (res == INF)
		cout << -1 << endl;
	else
		cout << res << endl;

	// bottom-up
	cout << Bottomup(k) << endl;

	return 0;
}

알고리즘 200일 프로젝트 - 83 day

'알고리즘 > BOJ' 카테고리의 다른 글

백준 11051번: 이항 계수 2  (0) 2020.06.30
백준 2133번: 타일 채우기  (0) 2020.06.26
백준 11048번: 이동하기  (0) 2020.06.25
백준 2167번: 2차원 배열의 합  (0) 2020.06.25
백준 9251번: LCS  (0) 2020.06.23

+ Recent posts