2293번: 동전 1
첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다.
www.acmicpc.net
문제
n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 각각의 동전은 몇 개라도 사용할 수 있다.
사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.
입력
첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다.
출력
첫째 줄에 경우의 수를 출력한다. 경우의 수는 231보다 작다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_2293 {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
public static void main(String[] args) throws Exception {
st = new StringTokenizer(in.readLine(), " ");
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int input[] = new int[n];
int dp[][] = new int[n + 1][k + 1];
for (int i = 0; i < n; i++) {
int tmp = Integer.parseInt(in.readLine());
input[i] = tmp;
}
for (int i = 0; i < n + 1; i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++) {
int current = input[i - 1];
if (j < current)
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = dp[i][j - current] + dp[i - 1][j];
}
}
System.out.println(dp[n][k]);
}
}
0/1 knapsack과 동일한 방법으로 문제를 해결하였다.
DP로 해결했기 때문에 다음과 같은 점화식이 유도되었다.
여기서 C(i)는 i번째로 고려할 코인의 가치이고, D(i, k)는 i번째 코인까지 사용해서 k를 만들 수 있는 경우의 수이다.
'Algorithms > BOJ' 카테고리의 다른 글
[Java] 2580. 스도쿠 (0) | 2021.04.07 |
---|---|
[Java] 18870. 좌표 압축 (0) | 2021.04.05 |
[Java] 9663. N-Queen (0) | 2021.03.29 |
[Java] 9205. 맥주 마시면서 걸어가기 (0) | 2021.03.26 |
[Java] 7569. 토마토 (0) | 2021.03.25 |