Problem
You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.
You may assume that you have an infinite number of each kind of coin.
Input
int: amount, int vector: coins[n]
Output
an integer representing the number of combinations that make up that amount
Constraints
1 <= coins.length <= 3001 <= coins[i] <= 50000 <= amount <= 5000
Sample Input
coins = [1,2,5], amount = 5
Sample Output
4 Explanation: there are four ways to make up the amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
Solution
This problem could be solved in polynomial time using Dynamic programming.
Dynamic Programming
This problem is similar to Coin Change problem, discussed here.
Optimal Substructure (Bottom up approach)
dp[j] represents the number of combinations that make up the amount j
Now according to optimal substructure:
for i = 0 to coins.size()-1:
for j = coins[i] to amount:
dp[j] = dp[j] + dp[j-coins[i]]
Base case & Initialisation
dp[0] = 1, number of ways to make sum = 0, is 1 (not including any coin) dp[j] = 0, if j > 0
Code Implementation
int change(int amount, vector<int>& coins) {
int n = (int) coins.size();
int dp[amount+1];
dp[0] = 1;
for(int i=1; i<=amount; i++) {
dp[i] = 0;
}
for(int i=0; i<n; i++) {
for (int j=coins[i]; j<=amount; j++) {
dp[j] += dp[j-coins[i]];
}
}
return dp[amount];
}
Time complexity of the above solution is O(n*amount) (n is the size of coins vector) and auxiliary space required is O(amount).