ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ DP ] 효율적인 화폐 구성
    알고리즘/이코테 - 실전 2021. 9. 8. 23:33

    난이도 : 중상  풀이시간 : 30분  시간제한 : 1초 

    [ DP ] 효율적인 화폐 구성

    N가지 종류의 화폐들의 개수를 최소한으로 이용해서 그 가치의 합이 M원이 되도록하려고 한다. 이 때 각 화폐는 몇 개라도 사용가능하며 사용한 화폐의 구성은 같지만 순서가 다른 것은 같은 경우로 구분한다.

     

    :: 입력 조건

     

    • 첫째 줄에 N, M이 주어진다.(1 <= N <= 100, 1 <= M <= 10,000)
    • 이후 N개의 줄에는 각 화폐의 가치가 주어진다. 화폐 가치는 10,000보다 작거나 같은 자연수이다.

     

    :: 출력 조건

     

    • 첫째 줄에 M원을 만들기 위한 최소한의 화폐 개수를 출력한다.
    • 불가능할 때는 -1을 출력한다.

     


     

      내   코드  

    점화식을 세울 때 

    dp[j] = min(dp[j], dp[j-n[i]]+1);

    이렇게 세우고

    이게 성립하려면

    dp[j]에 기본으로 설정 된 값이 0이면 안됨

     

    그리고 내가 점화식을 잘못 세움 ,,, 

    dp[j] = min(dp[j], dp[j-ns[i]] + dp[ns[i]]) < 이렇게 세움

     

      정답  코드  

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n, m;
    vector<int> arr;
    
    int main(void) {
        // 정수 N, M을 입력받기
        cin >> n >> m;
        
        // N개의 화폐 단위 정보를 입력 받기
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            arr.push_back(x);
        }
    
        // 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화
        vector<int> d(m + 1, 10001);
    
        // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업)
        d[0] = 0;
        for (int i = 0; i < n; i++) {
            for (int j = arr[i]; j <= m; j++) {
                // (i - k)원을 만드는 방법이 존재하는 경우
                if (d[j - arr[i]] != 10001) {
                    d[j] = min(d[j], d[j - arr[i]] + 1);
                }
            }
        }
    
        // 계산된 결과 출력
        if (d[m] == 10001) { // 최종적으로 M원을 만드는 방법이 없는 경우
            cout << -1 << '\n';
        }
        else {
            cout << d[m] << '\n';
        }
    }

     

    '알고리즘 > 이코테 - 실전' 카테고리의 다른 글

    O - [ 그리디 ] 큰 수의 법칙 - R  (0) 2021.10.05
    [ 최단거리 ] 미래도시  (0) 2021.09.27
    [ DP ] 바닥 공사  (0) 2021.08.23
    [ DP ] 개미전사  (0) 2021.08.23
    [ DP ] 1로 만들기  (0) 2021.08.23
준생e