ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 2293번
    문제 풀이 2020. 3. 21. 22:07

    2293 동전1


    문제


    n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 

    이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 

    각각의 동전은 몇 개라도 사용할 수 있다.

    사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.


    입력


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


    출력


    첫째 줄에 경우의 수를 출력한다. 경우의 수는 231보다 작다.




    풀이) 


    시간제한이 0.5초의 문제로 dp를 사용해서 풀어야하는 문제였다.

    dp[i] = i원의 가치를 표현할 수 있는 경우의 수의 합 

    으로 두고 문제를 풀었다.


    대략적인 작동방식을 보자면

    1. dp[0] = 1로 일단 초기화해둔다. (0원의 가치를 표현하는 방법은 아무 동전을 사용하지 않는 경우 1가지 존재)

    2. 각 동전을 사용할 수 있을 때마다, 가치 k마다 표현 가능한 경우의 수를 구한다.


    표로 예시를 들어보겠다.

    1. 1원 동전을 사용할 수 있을 때

     1

     10

    dp[k]

     1

     1


    k = 1일때는 0+1

    k = 2일때는 1+1

    k = 3일때는 1+1+1 .. 이런 방법으로 k = 10까지 각, 한가지 경우가 존재한다.


    2. 1원과 2원 동전을 사용할 수 있을 때

     10

     dp[k]


    k = 1일때는 2원 동전을 사용할 수없으니깐 1가지 그대로

    k = 2일때는 1+1뿐만 아니라 0+2로 표현가능하므로 2가지

    k = 3일때는 1+1+1, 1+2로 표현가능하므로 2가지

    k = 4일때는 1+1+1+1, 1+1+2, 2+2로 표현가능하므로 3가지

    .

    .

    .이런식으로 봤을 때 규칙을 알 수 있게 된다.

    dp[i] = dp[i] + dp[i - coin의 가치]


    예시 (k=2일때 2가지 경우가 있는데 k=4이면 k=2일때 경우의 수에다가 2원 동전 사용할 수 있으니깐 +1해서 3가지)


    3. 위와 같은 방법을 사용할 때, 1원 & 2원 & 5원의 동전을 사용할 수 있을 때

     10

     dp[k]

    10 


    따라서, 가치가 1,2,5인 동전 3가지를 사용할 수 있을때 10을 나타낼 수 있는 방법의 개수는 10개이다.


    코드)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <stdio.h>
    using namespace std;
     
    typedef long long ll;
    int n, k;
    int coin[100];
    ll dp[100001]; //dp[i] = i가치만큼 동전으로 표현할 수 있는 경우의 합
     
    int main() {
        scanf("%d %d"&n, &k);
        for (int i = 0; i < n; i++) {
            scanf("%d"&coin[i]);
        }
        
        dp[0= 1//0원 가치를 표현하는 방법 -> 아무 동전도 안사용하는 경우 1가지 존재
        for (int i = 0; i < n; i++) {
            for (int j = coin[i]; j <= k; j++) {
                if (j - coin[i] >= 0) {
                    dp[j] += dp[j - coin[i]];
                }
            }
        }
        printf("%lld", dp[k]);
     
        return 0;
    }
    cs


    결과)



    '문제 풀이' 카테고리의 다른 글

    [백준] 10472번 십자뒤집기  (1) 2020.03.24
    [백준] 2234번  (0) 2020.03.23
    [백준] 2579번  (0) 2020.03.21
    [백준] 16681번 등산  (0) 2020.03.21
    [백준] 16929번 two dots  (0) 2020.03.20

    댓글

Designed by Tistory.