문제
통증 N과 해당 값 만큼 통증 수치를 감소시켜주는 아이템 A, B가 주어진다.
통증 수치를 0으로 줄이기 위한 아이템의 최소 사용 개수를 출력하기.
단, 통증 수치가 0보다 작아지는 아이템을 사용할 수 없다.
통증 수치를 0으로 만들 수 없는 경우 -1을 출력한다.
생각할 것
처음에는 그리디로 문제를 해결하려 했다.
하지만 예외 상황이 발생했다.
입력
10000
4 13
의 경우 그리디로 해결하면 모든 경우를 확인하지 않았기에 -1의 결과가 나오게 된다.
따라서 이 문제는 dp로 해결해야 한다.
- 먼저 DP배열의 크기를 총 통증 크기 + 1로 만들고, 최대값으로 초기화 한다.
- 각 인덱스가 통증의 크기가 되고, 배열의 값은 사용할 수 있는 최소 약의 개수이다.
- 그리고 1부터 N 까지 모든 경우를 탐색한다.
- (i - 통증 감소 수치)가 0보다 큰 경우 해당 약을 사용할 수 있다는 것을 의미한다.
- 따라서 현재 dp값과 이전 인덱스에 약 하나를 더한 값을 비교해서 최소값을 설정한다.
- O(N)의 탐색이 끝난 뒤, dp[N]의 값이 처음 설정한 최대값과 동일하다면 불가능 한 경우이므로 -1을 출력하고, 그렇지 않다면 해당 값을 출력한다.
코드
#include <iostream>
#include <vector>
using namespace std;
int main() {
int N, A, B;
cin >> N >> A >> B;
vector<int> dp(N + 1, 1e9);
dp[0] = 0;
for (int i = 1; i <= N; i++) {
if (0 <= i - A) dp[i] = min(dp[i], dp[i - A] + 1);
if (0 <= i - B) dp[i] = min(dp[i], dp[i - B] + 1);
}
if (dp[N] == 1e9) cout << -1;
else cout << dp[N];
return 0;
}
반응형
'Problem solving > goorm' 카테고리의 다른 글
[구름톤 챌린지] 대체 경로 (C++) (0) | 2023.09.07 |
---|---|
[구름톤 챌린지] 중첩 점 (C++) (0) | 2023.09.06 |
[구름톤 챌린지] 발전기 (2) (C++) (0) | 2023.08.31 |
[구름톤 챌린지] 합 계산기 (C++) (0) | 2023.08.16 |