고인물을 지양하는 블로그

BOJ 2293 동전 1 본문

카테고리 없음

BOJ 2293 동전 1

yunjaeGong 2019. 7. 12. 22:51

https://www.acmicpc.net/problem/2293

 

2293번: 동전 1

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

www.acmicpc.net

 

//( D_{i,j} //) 를 다음과 같이 정의하자.

 

//( D_{i,j} : C_{i} //) 원 까지 이용해 j원을 만드는 경우의 수

 

따라서 //( C_{i} //) 원을 이용하는(할 수 있는) 경우, 이용하지 않는 경우 두 가지 경우로 나눌 수 있다.

각각의 경우는 

이다.

 

따라서 점화식은 다음과 같다.

코드 1

#include <cstdio>
#include <cstring>
#include <algorithm>
int N,K;

bool bound(int i, int j) {return i>=0&&i<N&&j>=0&&j<=K;}
int max(int a,int b) {return a>b?a:b;}

int main() {
    scanf("%d%d",&N,&K);
    int c[N],d[K+1];
    memset(d,0,K+1);
    for(int i=0;i<N;++i)
        scanf("%d",&c[i]);
    std::sort(c,c+N); // 오름차순으로 동전 정렬

    for(int i=0;i<N;++i)
        d[i][0] = 1;
    for(int i=1;i<=K;++i)
        d[0][i] = 1;
    // 초기조건

    for(int i=1;i<N;++i) {
        for(int j=1;j<=K;++j) {
            d[i][j] = (bound(i,j-c[i])?d[i][j-c[i]]:0) + (bound(i-1,j)?d[i-1][j]:0);
            // c[i]원을 사용 하는 경우, c[i]원을 사용 안하는 경우
        }
    }
        printf("%d",d[N-1][K]);
        // c[N-1]원까지 이용해 K원을 만드는 가짓수 출력
}

2차원 배열을 이용하면 점화식을 거의 그대로 옮긴 수준의 코드로 작성할 수 있다. 다만 문제에서는 메모리가 4MB로 제한돼 있으므로 메모리 초과가 발생한다. (발생했다)

 

코드 2

#include <cstdio>
#include <cstring>
#include <algorithm>

int N,K;

int main() {
    scanf("%d%d",&N,&K);
    int c[N],d[K+1];
    memset(d,0,sizeof(d));

    for(int i=0;i<N;++i)
        scanf("%d",&c[i]);
    d[0] = 1;

    for (int i=0;i<N;i++)
        for (int j=1;j<=K;j++)
            if (j>=c[i])
                d[j]+=d[j-c[i]]; 
    // c[i]원을 사용하지 않고 j원을 만드는 경우 + c[i]원을 사용하고 j원을 만드는 경우 합

        printf("%d",d[K]);
}

 

Comments