class Solution {
public int change(int amount, int[] coins) {
if (amount==0) return 1;
int[] dp = new int[amount+1];
for(int i=1; i<=amount; i++){
for(int coin: coins){
if(i%coin==0){
dp[i]+=1;
}
if(coin<i){
dp[i]=Math.max(dp[i],dp[i-coin]);
}
}
}
return dp[amount];
}
}
dp[i] = 금액 i를 만드는 방법의 수// ✘ 나누어떨어지는 경우만 카운트
if(i%coin==0){
dp[i]+=1;
}
i=5, coin=2일 때 2+2+1은 무시된다.
// ✘ 경우의 수는 더해야 함
dp[i]=Math.max(dp[i],dp[i-coin]);
조합 문제: 합산 필요 최솟값 문제: Max/Min 사용
동전 순서를 바꾼 조합을 중복으로 센다.
[1,2] vs [2,1] → 같은 조합class Solution {
public int change(int amount, int[] coins) {
int[] dp = new int[amount+1];
dp[0] = 1; // 0원을 만드는 방법 = 1가지
for(int coin: coins){
for(int i=coin; i<=amount; i++){
dp[i] += dp[i-coin];
}
}
return dp[amount];
}
}
핵심 차이:
+=로 경우의 수 누적잘못된 순서 (중복 발생):
for(int i=1; i<=amount; i++){
for(int coin: coins){
// [1,2]와 [2,1]을 다르게 카운트
}
}
올바른 순서:
for(int coin: coins){
for(int i=coin; i<=amount; i++){
// 동전을 순서대로 고려 → 중복 제거
}
}
동전 1만 사용:
dp[1] = 1 // [1]
dp[2] = 1 // [1,1]
dp[3] = 1 // [1,1,1]
동전 2 추가:
dp[2] += dp[0] = 2 // [1,1], [2]
dp[3] += dp[1] = 2 // [1,1,1], [1,2]
#LeetCode #DP #CoinChange #조합 #Java #중복제거