문제 출처 : https://www.acmicpc.net/problem/2293

 

2293번: 동전 1

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

www.acmicpc.net

다이나믹 프로그래밍으로 풀었다.

 

int n, k;
cin >> n >> k;
vector<int> coin(n + 1, 0);
vector<int> dp(k + 1, 0);
dp[0] = 1;

n과 k를 입력 받고 사이즈에 맞게 vector를 선언해준다.

coin은 n개의 동전 값을 받아 저장하고, dp는 금액을 만들 수 있는 방법의 수를 저장할 것이다.

dp[0]이 1인 이유는 0원을 만드는 방법은 아무것도 사용하지 않는 한가지 방법만 있기 때문이다.

 

for (int i = 0; i < n; i++) {
	cin >> coin[i];
}
for (int i = 0; i < n; i++) {
	for (int j = coin[i]; j <= k; j++) {
		dp[j] += dp[j - coin[i]];
	}
}
cout << dp[k];

동전의 가치를 입력 받고 2중 for문을 통해 각각의 동전마다 다이나믹 프로그래밍을 수행한다.

dp[j] += dp[j - coin[i]]는 j원을 만들 수 있는 방법의 수 dp[j]를 계산하는 것이다.

coin[i]는 현재 다이나믹 프로그래밍을 수행하는 동전의 가치이다.

j - coin[i]는 현재 만드려하는 j원에서 코인의 가치를 뺀 것으로 j - coin[i]를 만드는 방법의 수 dp[j - coin[i]에 coin[i]를 추가하면 j를 만드는 방법의 수가 되는 것이다.

 

예시와 같이 3 10 1 2 5를 입력했다고 했을 때

dp: 1 0 0 0 0 0 0 0 0 0 0 (index는 목표하는 금액을 의미합니다.)

초기에는 위와 같은 상태이다.

 

 

dp: 1 1 1 1 1 1 1 1 1 1 1

1원 동전에 대해 다이나믹 프로그래밍을 수행한 결과이다.

 

dp: 1 1 2 2 3 3 4 4 5 5 6

2원 동전에 대해 다이나믹 프로그래밍을 수행한 결과이다.

예를 들어 2원을 만드는 방법에는 1원 2개를 쓰는 방법과 2원 1개를 쓰는 방법, 총 2가지가 있을 것이다.

3원을 만드는 방법에는 1원 3개를 쓰는 방법과 2원 1개, 1원 1개를 쓰는 방법, 총 2가지가 있을 것이다.

4원을 만드는 방법은 2원을 만드는 방법인 1원2개, 2원 1개에서 2원을 추가하여 (1, 1, 2), (2, 2)와 1원만을 사용한 (1, 1, 1, 1) 총 3가지 방법이 있을 것이다.

위와 같이 j원을 만드는 방법은 현재 저장되어 있는 j원을 만드는 방법의 수에서 j - coin[i]을 만드는 방법의 수를 더해 나가면 구할 수 있다.

 

dp: 1 1 2 2 3 4 5 6 7 8 10

5원 동전에 대해 다이나믹 프로그래밍을 수행한 결과이다.

 

모든 동전에 대해 다이나믹 프로그래밍을 수행했다면 k원을 만드는 방법의 가지 수인 dp[k]를 출력해준다.

 

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

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n, k;
	cin >> n >> k;
	vector<int> coin(n + 1, 0);
	vector<int> dp(k + 1, 0);
	dp[0] = 1;
	for (int i = 0; i < n; i++) {
		cin >> coin[i];
	}
	for (int i = 0; i < n; i++) {
		for (int j = coin[i]; j <= k; j++) {
			dp[j] += dp[j - coin[i]];
		}
	}
	cout << dp[k];
	return 0;
}

전체코드

 

알고리즘

- 다이나믹 프로그래밍

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

[백준 1916] 최소비용 구하기 (C++)  (0) 2023.08.08
[백준 1238] 파티 (C++)  (0) 2023.08.07
[백준 1753] 최단경로 (C++)  (0) 2023.08.06
[백준 11438] LCA2 (C++)  (0) 2023.07.25
[백준 2042] 구간 합 구하기 (C++)  (0) 2023.07.21

+ Recent posts