Given a list of N coins, their values (V1, V2, ... , VN), and the total sum S. Find the minimum number of coins the sum of which is S (we can use as many coins of one type a
int getMinCoins(int arr[],int sum,int index){
int INFINITY=1000000;
if(sum==0) return 0;
else if(sum!=0 && index<0) return INFINITY;
if(arr[index]>sum) return getMinCoins(arr, sum, index-1);
return Math.min(getMinCoins(arr, sum, index-1), getMinCoins(arr, sum-arr[index], index-1)+1);
}
Consider i-th coin. Either it will be included or not. If it is included, then the value sum is decreased by the coin value and the number of used coins increases by 1. If it is not included, then we need to explore the remaining coins similarly. We take the minimum of two cases.
As already pointed out, Dynamic Programming suits best for this problem. I have written a Python program for this:-
def sumtototal(total, coins_list):
s = [0]
for i in range(1, total+1):
s.append(-1)
for coin_val in coins_list:
if i-coin_val >=0 and s[i-coin_val] != -1 and (s[i] > s[i-coin_val] or s[i] == -1):
s[i] = 1 + s[i-coin_val]
print s
return s[total]
total = input()
coins_list = map(int, raw_input().split(' '))
print sumtototal(total, coins_list)
For input:
12
2 3 5
The output would be:
[0, -1, 1, 1, 2, 1, 2, 2, 2, 3, 2, 3, 3]
3
The list_index is the total needed and the value at list_index is the no. of coins needed to get that total. The answer for above input(getting a value 12) is 3 ( coins of values 5, 5, 2).
For a fast recursive solution, you can check this link: java solution
I am going through the minimum steps required to find the perfect coin combination.
Say we have coins = [20, 15, 7]
and monetaryValue = 37
. My solution will work as follow:
[20] -> sum of array bigger than 37? NO -> add it to itself
[20, 20] greater than 37? YES (20 + 20) -> remove last and jump to smaller coin
[20, 15] 35 OK
[20, 15, 15] 50 NO
[20, 15, 7] 42 NO
// Replace biggest number and repeat
[15] 15 OK
[15, 15] 30 OK
[15, 15, 15] 45 NO
[15, 15, 7] 37! RETURN NUMBER!
I don't know about dynamic programming but this is how I would do it. Start from zero and work your way to S
. Produce a set with one coin, then with that set produce a two-coin set, and so on... Search for S
, and ignore all values greater than S
. For each value remember the number of coins used.
This is a classic Knapsack problem, take a look here for some more information: Wikipedia Knapsack Problem
You should also look at some sorting, specifically sorting from Largest to Smallest values.
I think the approach you want is like this:
You know that you want to produce a sum S
. The only ways to produce S
are to first produce S-V1
, and then add a coin of value V1
; or to produce S-V2
and then add a coin of value V2
; or...
In turn, T=S-V1
is producible from T-V1
, or T-V2
, or...
By stepping back in this way, you can determine the best way, if any, to produce S
from your V
s.