Open In App

PHP Program for Coin Change | DP-7

Write a PHP 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}.



PHP 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.

The final result will be the sum of both cases.

Base case:

Below is the Implementation of the above approach:




<?php
// Recursive PHP program for
// coin change problem.
 
// Returns the count of ways we can
// sum coins[0...n-1] coins to get sum "sum"
function coun($coins, $n, $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 coun($coins, $n - 1,$sum ) +
        coun($coins, $n, $sum - $coins[$n - 1] );
}
 
    // Driver Code
    $coins = array(1, 2, 3);
    $n = count($coins);
    echo coun($coins, $n, 5);
     
// This code is contributed by Sam007
?>

Output
5

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

PHP 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:

Below is the implementation of the above approach:




<?php
 
function countWays($coins, $n, $sum, &$dp) {
    // Base Case
    if ($sum == 0) {
        $dp[$n][$sum] = 1;
        return 1;
    }
 
    // If the subproblem is previously calculated, return the result
    if ($n <= 0 || $sum < 0) {
        return 0;
    }
 
    if ($dp[$n][$sum] != -1) {
        return $dp[$n][$sum];
    }
 
    // Two options for the current coin
    $dp[$n][$sum] = countWays($coins, $n, $sum - $coins[$n - 1], $dp)
        + countWays($coins, $n - 1, $sum, $dp);
 
    return $dp[$n][$sum];
}
 
$tc = 1;
// Read input here if needed
 
while ($tc--) {
    $n = 3;
    $sum = 5;
    $coins = [1, 2, 3];
    $dp = array_fill(0, $n + 1, array_fill(0, $sum + 1, -1));
    $res = countWays($coins, $n, $sum, $dp);
    echo $res . PHP_EOL;
}
 
?>

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)

PHP 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:




<?php
 
function countDistinctWays($coins, $n, $sum) {
    $dp = array_fill(0, $sum + 1, 0);
    $dp[0] = 1;
 
    for ($i = 0; $i < $n; $i++) {
        for ($j = $coins[$i]; $j <= $sum; $j++) {
            $dp[$j] += $dp[$j - $coins[$i]];
        }
    }
 
    return $dp[$sum];
}
 
$coins = [2, 5, 3, 6];
$n = 4;
$sum = 10;
echo countDistinctWays($coins, $n, $sum) . PHP_EOL;
?>

Output
5

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

PHP 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:

Below is the implementation of the above approach:




<?php
function count_1( &$coins, $n, $sum )
{
    // table[i] will be storing the number
    // of solutions for value i. We need sum+1
    // rows as the table is constructed in
    // bottom up manner using the base case (sum = 0)
    $table = array_fill(0, $sum + 1, NULl);
 
    // Base case (If given value is 0)
    $table[0] = 1;
 
    // Pick all coins one by one and update
    // the table[] values after the index
    // greater than or equal to the value
    // of the picked coin
    for($i = 0; $i < $n; $i++)
        for($j = $coins[$i]; $j <= $sum; $j++)
            $table[$j] += $table[$j - $coins[$i]];
 
    return $table[$sum];
}
 
// Driver Code
$coins = array(2, 5, 3, 6);
$n = sizeof($coins);
$sum = 10;
$x = count_1($coins, $n, $sum);
echo $x;
 
// This code is contributed
// by ChitraNayal
?>

Output
5

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

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


Article Tags :