Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 27 | 28 | 29 | 30 | 31 |
Tags
- BOJ 2407
- BOJ 6593
- BOJ 5568
- 다익스트라
- MySQL
- BOJ 1697
- javascript
- BOJ 2234
- BOJ 2167
- DP
- BOJ 4948
- BOJ 2213
- BOJ 1926
- priority_queue
- AWS
- Lambda
- 플로이드 와샬
- 분할과 정복
- spring security
- BOJ 4485
- BOJ 2146
- Coercion
- BOJ 1074
- serverless
- BOJ 11726
- springboot
- BOJ 1912
- BOJ 2012
- 조합 알고리즘
- BOJ 5791
Archives
- Today
- Total
고인물을 지양하는 블로그
BOJ 2293 동전 1 본문
https://www.acmicpc.net/problem/2293
//( 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