문제
백준 9084번 - 동전
아이디어
- DP로 해결할 수 있는 기본적인 문제이다.
M
원의 경우의 수를 찾기 위해 1원부터 M
원까지 점진적으로 경우의 수를 찾아나가야 한다.
dp[M][N]
을 M
원을 N
개의 동전으로 만들 수 있는 경우의 수라고 가정한다.
- 0원을 만드는 것은 동전을 하나도 안 고르면 되므로 1로 초기화 할 수 있다.
- 1원부터 동전 액수와 비교하여 동전이 작거나 같다면 현재
M
원에는 N
번째 동전이 구성될 수 있다는 뜻이므로 M
원에서 N
번째 동전의 액수만큼 뺀 경우의 수와(dp[M-coin[N]][N]
) 이전 번째 동전의 경우의 수를(dp[M][N-1]
)를 합한다.
- 만약
M
원보다 동전 액수가 더 크다면 현재 동전은 M
원에 구성될 수 없으므로 이전 번째 동전의 경우의 수를 그대로 따른다.
- 이런 식으로 풀어나가
dp[M][N]
을 출력한다.
예상 시간 복잡도
코드 구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BJ_9084 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
while (t-- > 0) {
int n = Integer.parseInt(br.readLine());
int[] coins = new int[n + 1];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++) {
coins[i] = Integer.parseInt(st.nextToken());
}
int m = Integer.parseInt(br.readLine());
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= n; i++) {
dp[0][i] = 1;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (coins[j] <= i) {
dp[i][j] = dp[i - coins[j]][j] + dp[i][j - 1];
} else {
dp[i][j] = dp[i][j - 1];
}
}
}
System.out.println(dp[m][n]);
}
}
}