https://www.acmicpc.net/problem/14916
dp 문제이고,
입력된 n값에 대해 2원, 5원으로 거슬러 줄 때 최소의 동전개수를 사용하는 문제입니다.
메모이제이션을 활용하여 단계별로 값을 배열에 저장해 계산해 줍니다.
문제 분석
먼저 배열 간 값들의 관계를 도출하기 위해 (점화식) 값을 직접 계산해 봅니다.
구성할 수 없는 경우는 -1로 작성하였습니다.
| n | 최소 동전 개수 |
| 1 | -1 |
| 2 | 1 |
| 3 | -1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 3 |
| 7 | 2 |
| 8 | 4 |
이제 값들 간 관계를 구해봅시다. 점화식은 대충 a(n) 이라 놓고
n이 4인 경우에 최소 동전 개수는 2원짜리 동전 하나씩을 사용하니 1 + 1 = 2 로 계산했습니다.
이 경우 a(4) = a(2) + a(2) 라고 할 수 있습니다.
n이 7인 경우는 a(7) = a(5) + a(2) 로 계산될 수 있습니다.
그런데 n= 10 인 경우 같은 경우에는 거슬러 줄수 있는 경우의 수가 아래와 같이 2가지 입니다.
1. 2 + 2 + 2 + 2 + 2
2. 5 + 5
이런 경우 사용된 동전의 최소값(2) 를 배열에 넣어야겠죠.
따라서 a(n-2) + a(2)와 a(n-5) + a(5) 중 최소값을 구해서 배열에 넣어줍니다.
소스 코드
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <climits>
#include <algorithm>
using namespace std;
int dp[100001];
int findval(int n)
{
if (dp[n]!= 0)
{
return dp[n];
}
else
{
int tmp1 = findval(n - 2) + dp[2];
int tmp2 = findval(n - 5) + dp[5];
if (tmp1 >0 && tmp2 > 0)
{
dp[n] = min(tmp1, tmp2);
}
else if (tmp1 > 0)
{
dp[n] = tmp1;
}
else
{
dp[n] = tmp2;
}
return dp[n];
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
dp[0] = -1;
dp[1] = -1;
dp[2] = 1;
dp[3] = -1;
dp[4] = 2;
dp[5] = 1;
cout << findval(n);
}
'백준 > 실버' 카테고리의 다른 글
| [백준 15729]- 방탈출(c++) (0) | 2026.03.25 |
|---|---|
| [백준 3060]- 욕심쟁이 돼지(c++) (0) | 2026.03.23 |
| [백준 1340] - 연도 진행바 (0) | 2026.03.05 |
| [백준 3758] - KCPC(C++) (0) | 2026.02.23 |
| [백준 1991] - 트리 순회(C++) (0) | 2025.12.24 |