Closed icegosimperson closed 1 month ago
🤔 시간복잡도 고려사항
1 ≤ 동전 수 ≤ 20
, 1 ≤ 동전 금액 ≤ 10000
조합으로 풀 경우 10000C20 으로 연산불가
DP 로 풀 경우 O(동전수*동전금액)
으로 10^5
연산 가능💡 풀이 아이디어
[M-현재코인]
의 경우의 수와 동일하다메모리제이션 테이블을 만들 때 규칙성을 찾기 위해 어떻게 이미 계산된 값을 재사용할지 생각하기....................... 참고 블로그
🤔 시간복잡도 고려사항
💡 풀이 아이디어
처음 아이디어 (틀림)
// 초기화
int[] dp = new int[M + 1];
Arrays.fill(dp, Integer.MIN_VALUE);
dp[0] = 0;
// 점화식
for (int c : coin) {
for (int i = c; i <= M; i++) {
if (dp[i-c] != Integer.MIN_VALUE){
dp[i] = dp[i] == Integer.MIN_VALUE ? 1 : dp[i] + 1;
}
}
}
수정 버전
// 초기화
int[] dp = new int[M + 1];
dp[0] = 1;
// 점화식
for (int c : coin) {
for (int i = c; i <= M; i++) {
dp[i] += dp[i - c];
}
}
🤔 시간복잡도 고려사항
1 <= 동전의 가지 수 <= 20
이고, 동전의 개수 제한이 없기 때문에 완전 탐색으로 모든 경우를 구하는 경우는 불가능하다고 생각함O(N×M)
에 해결 가능💡 풀이 아이디어
int[] dp
: M원을 만들 때의 경우의 수dp[0]
: 0원을 만드는 경우는 모든 동전을 사용하지 않는 경우이므로 1로 초기화현재 경우의 수 = 현재 경우의 수 + dp[i - 현재 동전]
으로 구해줌
for(int c: coin) {
for(int i = 0; i < dp.length; i++) {
if(i - c < 0) continue;
dp[i] += dp[i - c];
}
}
🤔 시간복잡도 고려사항
💡 풀이 아이디어
for(int i=0; i<N; i++){
for(int j=coins[i]; j<M+1; j++){
dp[j] += dp[j - coins[i]]; // 해당 동전 사용할 수 있는 금액 +
}
🤔 시간복잡도 고려사항
=> 테스트케이스 T 동전 가지수 N 만들금액 M == 2,000,000 : 선형탐색으로 생각해보기
💡 풀이 아이디어
dp[j] = dp[j] + dp[j-coin[i]];
🤔 시간복잡도 고려사항
💡 풀이 아이디어
DP
, knapsack
// knapsack - 중복 사용 가능
for (int coin : coins)
// 현재 동전으로 만들 수 있는 조합의 수 계산
for (int i = coin; i < m + 1; i++)
dp[i] += dp[i - coin];