본문 바로가기
Algorithm/Dynamic Programming

BOJ G5 2294 동전2 JAVA

by rueMi 2024. 1. 7.

 

2294번: 동전 2

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

www.acmicpc.net


문제 읽기

예전에 동전 1 문제를 풀었었는데 DP 문제를 잘 못하다 보니 그때도 고생했었다. 결국 풀지 못하고 블로그 찾아봤던 기억이..

이번에는 풀어보자! 하고 열심히 적으면서 했는데 예전 풀이가 기억나서 거기에 갇혀 좀 헤맸다. 기억이 아니라 논리에 의존해서 DP 문제를 풀고 싶구나.. 많이 풀다 보면 되겠지! 하는 생각이다.


문제 풀이

여러 차례 삽질했다. 바로 최종 문제 풀이로 넘어가도 상관 없을 듯 하다.

1차 삽질 : 2차원 배열. 동전의 종류 / 사용하는 동전의 개수

예전 동전1 문제를 풀었을 때 2차원 배열을 썼던 기억 때문에 당연히 2차원 배열이라 생각하고 접근했다. 동전의 종류마다 사용하는 동전 개수를 하나씩 증가 시키며 가치의 합을 표의 값으로 채워넣었다. 그래서 다음과 같이 나왔는데, 표에 최종적으로 뭘 저장해야 할 지도 모르겠고, 아무리 봐도 이건 아닌 거 같았다.

 

2차 삽질 : 2차원 배열. 동전의 종류 / 가치의 합

아차차 하고 표의 열에 들어가는 값을 바꿨다. 보통 냅색 문제가 N, W를 각각 행렬로 보는 것도 잇따라 기억났다. 바꾸니까 뭔가 되는 거 같았고, 점화식까지 세웠다.

그런데 넣으니까 계속 3퍼센트에서 틀렸다고 나왔다. 뭐가 문제지 하고 문제를 계속 읽어보고 입력값의 중복도 제거해보고 답이 없으면 -1로 출력하고 여러가지 했는데 변화가 없었다(꺾임)

3차.. 블로그 서칭.. 최종 풀이

 

[알고리즘] - 백준 2294번 : 동전2 (JAVA)

문제 풀러가기입력받은 k 길이 만큼의 배열을 Integer.MAX_VALUE로 초기화.배열을 k길이만큼 만드는 이유는 배열의 인덱스를 입력받은 동전으로 만들어야 하는 가치라고 생각하기 위해 ex) dp3은 3의

velog.io

결국 블로그 찾아봤다. 다른 점은 다음과 같다.

  • 1차원 DP 배열을 쓴다
    • 1~K까지의 가치의 합 배열
  • 이전 값을 갱신하여 같은 곳에 채운다
  • DP 배열의 초기화
    • 0번째 위치를 제외하고는 큰 값으로 채워준다.
  • 점화식
    • DP[k] = Math.min(DP[k], DP[k-coins[n]] + 1)
    사용하는 동전의 종류를 하나씩 증가 시키면서,새로운 동전도 함께 사용했을 때 k라는 값을 만들 수 있는 동전의 개수를 비교해서 ⇒ DP[k-coins[n]] + 1
  • 최솟값을 저장한다
  • 현재까지 동전을 사용했을 때 k라는 값을 만들 수 있는 동전의 개수와, ⇒ DP[k]

코드

package ps.ㄱSolving;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class BOJ_G5_2294_동전2 {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(in.readLine());
        int N = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        int[] coins = new int[N];
        for (int i = 0; i < N; i++){
            coins[i] = Integer.parseInt(in.readLine());
        }

        //dp logic
        int[] dp = new int[K+1];
        for (int j = 1; j < K+1; j++){
            dp[j] = 1000000;
        }
        for (int n = 1; n < N+1; n++){
            for (int k = coins[n-1]; k < K+1; k++){
                dp[k] = Math.min(dp[k-coins[n-1]] + 1, dp[k]);
            }
        }

//        System.out.println(Arrays.toString(dp));
        System.out.println((dp[K] == 1000000)? -1 : dp[K]);
    }
}

 

살짝 한 풀이처럼 되어버렸지만.. DP 잘 푸는 날까지 화이팅..!!

 

'Algorithm > Dynamic Programming' 카테고리의 다른 글

BOJ S1 1890 점프 JAVA  (0) 2024.01.08
BOJ G4 2133 타일 채우기 JAVA  (0) 2024.01.08
BOJ S3 9461 파도반수열 JAVA  (0) 2024.01.06
BOJ S1 9465 스티커 JAVA  (0) 2023.11.23
BOJ G5 12865 평범한 배낭 JAVA  (0) 2023.11.22