Open In App

C Program for Coin Change | DP-7

Improve
Improve
Like Article
Like
Save
Share
Report

Write a C program for a given integer array of coins[ ] of size N representing different types of denominations and an integer sum, the task is to find the number of ways to make a sum by using different denominations.

Examples:

Input: sum = 4, coins[] = {1,2,3},
Output: 4
Explanation: there are four solutions: {1, 1, 1, 1}, {1, 1, 2}, {2, 2}, {1, 3}.

Input: sum = 10, coins[] = {2, 5, 3, 6}
Output: 5
Explanation: There are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}.

C Program for Coin Change using Recursion:

Recurrence Relation:

count(coins,n,sum) = count(coins,n,sum-count[n-1]) + count(coins,n-1,sum)

For each coin, there are 2 options.

  • Include the current coin: Subtract the current coin’s denomination from the target sum and call the count function recursively with the updated sum and the same set of coins i.e., count(coins, n, sum – coins[n-1] )
  • Exclude the current coin: Call the count function recursively with the same sum and the remaining coins. i.e., count(coins, n-1,sum ).

The final result will be the sum of both cases.

Base case:

  • If the target sum (sum) is 0, there is only one way to make the sum, which is by not selecting any coin. So, count(0, coins, n) = 1.
  • If the target sum (sum) is negative or no coins are left to consider (n == 0), then there are no ways to make the sum, so count(sum, coins, 0) = 0.
  • Coin Change | DP-7

Below is the Implementation of the above approach:

C




// Recursive C program for
// coin change problem.
#include <stdio.h>
 
// Returns the count of ways we can
// sum coins[0...n-1] coins to get sum "sum"
int count(int coins[], int n, int sum)
{
    // If sum is 0 then there is 1 solution
    // (do not include any coin)
    if (sum == 0)
        return 1;
 
    // If sum is less than 0 then no
    // solution exists
    if (sum < 0)
        return 0;
 
    // If there are no coins and sum
    // is greater than 0, then no
    // solution exist
    if (n <= 0)
        return 0;
 
    // count is sum of solutions (i)
    // including coins[n-1] (ii) excluding coins[n-1]
    return count(coins, n - 1, sum)
        + count(coins, n, sum - coins[n - 1]);
}
 
// Driver program to test above function
int main()
{
    int i, j;
    int coins[] = { 1, 2, 3 };
    int n = sizeof(coins) / sizeof(coins[0]);
    printf("%d ", count(coins, n, 5));
    getchar();
    return 0;
}


Output

5 

Time Complexity: O(2sum)
Auxiliary Space: O(sum)

C Program for Coin Change using Dynamic Programming (Memoization) :

The above recursive solution has Optimal Substructure and Overlapping Subproblems so Dynamic programming (Memoization) can be used to solve the problem. So 2D array can be used to store results of previously solved subproblems.

Step-by-step approach:

  • Create a 2D dp array to store the results of previously solved subproblems.
  • dp[i][j] will represent the number of distinct ways to make the sum j by using the first coins.
  • During the recursion call, if the same state is called more than once, then we can directly return the answer stored for that state instead of calculating again.

Below is the implementation of the above approach:

C




#include <stdio.h>
 
int N, SUM;
 
// Recursive function to count the number of distinct ways
// to make the sum by using n coins
int count(int coins[], int n, int sum,
          int dp[N + 1][SUM + 1])
{
    // Base Case
    if (sum == 0)
        return dp[n][sum] = 1;
 
    // If the number of coins is 0 or the sum is less than
    // 0, there is no way to make the sum.
    if (n == 0 || sum < 0)
        return 0;
 
    // If the subproblem is previously calculated, then
    // return the result
    if (dp[n][sum] != -1)
        return dp[n][sum];
 
    // Two options for the current coin
    return count(coins, n, sum - coins[n - 1], dp)
           + count(coins, n - 1, sum, dp);
}
 
int main()
{
    int tc = 1;
    while (tc--) {
        int n, sum;
        n = 4;
        sum = 10;
        int coins[] = { 2, 5, 3, 6 };
        int dp[n + 1][sum + 1];
 
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= sum; j++) {
                dp[i][j] = -1;
            }
        }
        N = n, SUM = sum;
        int res = count(coins, n, sum, dp);
        printf("%d\n", res);
    }
 
    return 0;
}


Output

5

Time Complexity: O(N*sum), where N is the number of coins and sum is the target sum.
Auxiliary Space: O(N*sum)

C Program for Coin Change using Dynamic Programming (Tabulation):

  • Create a 2D dp array with rows and columns equal to the number of coin denominations and target sum.
  • dp[0][0] will be set to 1 which represents the base case where the target sum is 0, and there is only one way to make the change by not selecting any coin.
  • Iterate through the rows of the dp array (i from 1 to n), representing the current coin being considered.
    • The inner loop iterates over the target sums (j from 0 to sum).
      • Add the number of ways to make change without using the current coin, i.e., dp[i][j] += dp[i-1][j].
      • Add the number of ways to make change using the current coin, i.e., dp[i][j] += dp[i][j-coins[i-1]].
  • dp[n][sum] will contain the total number of ways to make change for the given target sum using the available coin denominations.

Below is the implementation of the above approach:

C




#include <stdio.h>
 
// Returns total distinct ways to make sum using n coins of
// different denominations
int count(int coins[], int n, int sum)
{
    // 2D dp array where n is the number of coin
    // denominations and sum is the target sum
    int dp[n + 1][sum + 1];
     
    // Initialize the dp array
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= sum; j++) {
            dp[i][j] = 0;
        }
    }
     
    // Represents the base case where the target sum is 0,
    // and there is only one way to make change: by not
    // selecting any coin
    dp[0][0] = 1;
     
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= sum; j++) {
            // Add the number of ways to make change without
            // using the current coin
            dp[i][j] += dp[i - 1][j];
             
            if ((j - coins[i - 1]) >= 0) {
                // Add the number of ways to make change
                // using the current coin
                dp[i][j] += dp[i][j - coins[i - 1]];
            }
        }
    }
     
    return dp[n][sum];
}
 
int main()
{
    int coins[] = {2, 5, 3, 6};
    int n = 4;
    int sum = 10;
    printf("%d\n", count(coins, n, sum));
    return 0;
}


Output

5

Time complexity : O(N*sum)
Auxiliary Space : O(N*sum)

C Program for Coin Change using the Space Optimized 1D array:

In the above tabulation approach we are only using dp[i-1][j] and dp[i][j] etc, so we can do space optimization by only using a 1d dp array.

Step-by-step approach:

  • Create a 1D dp array, dp[i] represents the number of ways to make the sum i using the given coin denominations.
  • The outer loop iterates over the coins, and the inner loop iterates over the target sums. For each dp[j], it calculates the number of ways to make change using the current coin denomination and the previous results stored in dp.
  • dp[sum] contains the total number of ways to make change for the given target sum using the available coin denominations. This approach optimizes space by using a 1D array instead of a 2D DP table.

Below is the implementation of the above approach:

C




#include <stdio.h>
#include <string.h>
 
int count(int coins[], int n, int sum)
{
    int dp[sum + 1];
    memset(dp, 0, sizeof(dp));
    dp[0] = 1;
 
    for (int i = 0; i < n; i++) {
        for (int j = coins[i]; j <= sum; j++) {
            dp[j] += dp[j - coins[i]];
        }
    }
    return dp[sum];
}
 
int main()
{
    int coins[] = {2, 5, 3, 6};
    int n = sizeof(coins) / sizeof(coins[0]);
    int sum = 10;
    printf("%d\n", count(coins, n, sum));
    return 0;
}


Output

5

Time complexity : O(N*sum)
Auxiliary Space : O(sum)

Please refer complete article on Coin Change | DP-7 for more details!



Last Updated : 09 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads