I am making a game which consists of coin denominations of $10, $5, $3, and $1. The player may have 0 or more of each type of currency in his inventory with a maximum of 15 coins in total. I am trying to figure out how to properly select coins so that the least amount of change is given in return. At first I thought this was going to be easy to solve, but now I'm having trouble wrapping my head around it.
Here are two examples that explain the situation further:
Example 1:
The user is carrying these coins: $5, $3, $3, $3, $1, $1, $1, $1 and want to buy an item for $12. The solution would be to pay with $5, $3, $3, $1 and give no change.
Example 2:
The user does not have any $1 coins, and is carrying $5, $3, $3, $3, $3. An item is bought for $12 so they pay with $5, $3, $3, and $3 and change of $2 is given back.
Since we select the larger coins first, what I can't figure out is how to know if there are enough lower valued coins ($1 in this case) in the player's inventory to accommodate example 1, and if there aren't enough to use more of the higher valued coins as in example 2.
A further issue is seen in the following example, though I'd be happy just getting the above two examples working:
Example 3: The user is carrying these coins: $5, $3, $3, $3. The player buys something for $6. It would be better to use $3 and $3 and return no change rather than using $5 and $3 and give $2 in change.
I believe the first two examples can be solved using recursion and a variation of the greedy algorithm.
For the bounty award:
I have added my own answer below as a temporary solution for now. However, I like the approach of Mr. Llama's below (see the link he references) and would like to find a PHP example to satisfy this. I believe this approach does not need recursion and uses memoization.
If there are multiple options for the least amount of change then I would like the tie to be given to the one that pays with the least amount of coins.
Given an unlimited supply of coins of given denominations, find the minimum number of coins required to get the desired change. For example, consider S = { 1, 3, 5, 7 } . If the desired change is 15, the minimum number of coins required is 3. (7 + 7 + 1) or (5 + 5 + 5) or (3 + 5 + 7)
Example 1: Suppose you are given the coins 1 cent, 5 cents, and 10 cents with N = 8 cents, what are the total number of combinations of the coins you can arrange to obtain 8 cents. Input: N=8 Coins : 1, 5, 10 Output: 2 Explanation: 1 way: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 8 cents. 2 way: 1 + 1 + 1 + 5 = 8 cents.
So, we create a minCoins array - minCoins[sum+1] where minCoins[i] represents minimum number of coins required to make change for amount = i. We build up the array in bottom up manner starting with minCoins[0]. The time complexity of the Dynamic Programming solution is O(n*sum). The space complexity is O(sum).
Problem Statement We are given an array of coins having different denominations and an integer sum representing the total money, you have to return the fewest coins that you will need to make up that sum if it's not possible to construct that sum then return -1. Explanation: There is no combination present with sum 15.
The problem can be defined as:
Return a subset of items where the sum is closest to x, but >= x.
This problem is called the subset sum problem. It is NP-complete. You won't find a perfect algorithm that runs in pseudo-polynomial time, only imperfect heuristics.
However, if the number of coins is very small, then an exhaustive search of the solution space will certainly work.
If the number of coins is larger, then you should look at Wikipedia for an overview: https://en.wikipedia.org/wiki/Subset_sum_problem#Polynomial_time_approximate_algorithm
I had a similar problem except instead of being allowed to go over, the combination had to stay under the target amount. In the end, I used the dynamic approach presented in this answer. You should be able to use it too.
It goes something like this:
*: We can make this optimization because we don't particularly care which coins are used in the combination, only the sum value of the collection of coins.
The above algorithm can be optimized a bit if you use the sum value as the key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With