거스름돈 계산하기 2
2024-09-26
#JAVA#프로그래머스
문제 설명
거스름돈 계산하기 2
정답률 34% · 제출 112회 · 예상 소요 시간 60분
곰돌이는 코드트리 마트에서 현재 일 하고 있습니다. 코드트리 마트에는 현재 N 가지의 동전들을 가지고 있고, 각 동전은 Ai 개를 가지고 있습니다.
곰돌이가 동전을 최소로 사용하여 거스름돈을 돌려주는 방법을 구하는 프로그램을 작성하세요.
입력 형식
첫번째 줄에 동전의 가지 수 N 과 돌려줘야 하는 거스름돈의 액수 S 가 공백을 사이에 두고 주어집니다.
두번째 줄부터 N 개의 줄에 걸쳐 각 동전의 가치 Vi 와, 가지고 있는 동전의 개수 Ai 가 공백을 사이에 두고 주어집니다.
단, 각 동전의 가치는 모두 다릅니다.
- •
1 ≤ N ≤ 1,000
- •
1 ≤ S ≤ 5,000
- •
1 ≤ Vi ≤ 2,000
- •
1 ≤ Ai ≤ 20
출력 형식
첫번째 줄에 곰돌이가 가장 적게 사용한 동전의 개수를 출력하세요. 만약 해당 거스름돈을 만들 수 없다면, -1을 출력하세요.
입출력 예제
예제1
입력:
5 21
1 1
2 3
3 4
4 5
5 2
출력:
5
예제2
입력:
2 20
3 2
9 3
출력:
1
문제 풀이 시간 : 1시간
문제 풀이 :
처음엔 그냥 되게 간단한 dp 문제인줄 알았는데
막상 풀려고 하니 dp를 어떤 식으로 코드를 짜야하는지 헷갈렸다.
초기 코드를 가져오고 싶은데
코드트리는 이미 지난 시험의 코드는 다시 볼 수 없는 것 같다.
그래서 기존 코드는 가져올 수 없지만
그냥 너무 생각을 깊게 했던게 독이 됐던 것 같다.
그래서 코드가 너무 더러웠고 복잡했다.
그래서 며칠 뒤에 다시 새로운 마음으로 문제를 봤더니 아주 간단한 문제라는 것을 알 수 있었다.
최종 코드
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int S = Integer.parseInt(st.nextToken());
int[] dp = new int[S+1]; //최소 거스름돈 수를 저장하는 dp 배열
for(int i=1;i<=S;i++){ //0원일떄를 제외하고 모두 무한으로 설정
dp[i] = Integer.MAX_VALUE;
}
for(int i=0;i<N;i++){
st = new StringTokenizer(br.readLine());
int price = Integer.parseInt(st.nextToken()); //동전의 가격
int count = Integer.parseInt(st.nextToken()); //동전을 가지고 있는 개수
for(int j=0;j<=S;j++){ //0원부터 S원까지 반복
if(dp[j]!=Integer.MAX_VALUE){ //현재 가격의 동전 개수가 무한이 아니라면
for(int k=1;k<=count;k++){ //동전의 개수만큼 반복
int idx = j+k*price; //다음 가격
if(idx>S){ //얻고자하는 가격을 넘으면 종료
break;
}
dp[idx] = Math.min(dp[idx],dp[j]+k); //원래 개수와 새로운 개수를 비교해서 최소값 저장
}
}
}
}
if(dp[S]==Integer.MAX_VALUE){ //해당 가격의 동전 개수가 무한이면 구할 수 없는 것
System.out.println(-1);
}
else{ //구해져 있다면 출력
System.out.println(dp[S]);
}
}
}