Consider a cashier machine that takes payments in coins. We feed the machine coins one by one until the value is more than the amount we should have paid. Then the machine returns the extra amount in coins in the least number of coins possible. So we have k type of coins and a limited amount of each type. Also the machine has an unlimited amount of each of the k types of coins so it can return us the exact amount it should (there is always coin with value 1). So we want to minimize the number of coins we have after we have paid for the items we have bought. Consider this example: We have 3 kinds of coins of values 1, 2 and 4 and we have to pay 15 dollars. We have 10 coins with value 1, 7 coins with value 4 and 5 coins with value 2. There are multiple ways to minimize our coins after the process. One of them is to give the machine 10 coins with value 1 and 3 coins with value 2. Thus we have paid 16 dollars with 13 coins and the machine should return to us 1 dollar and it returns us 1 coin with value 1. So we have spent 12 coins. The other way is to give the machine 9 coins with value 1 and 3 coins with value 2 and the machine doesn't return us anything. So we have paid 12 coins.
My approach to the problem is to divide the problem to two separate coin change problem. The easier problem is when the machine returns us the extra amount of money we have paid. I think this is a simple coin change problem that we want to change some amount of money to the minimum number of coins. The main problem is to pay the machine some maximal amount of coin with the restrictions mentioned above. The restrictions were that we have limited number of each coin and if want to pay A dollars the machine stops receiving coins when the amount of money we have paid becomes equal or greater than A. So For example if we have to pay to 15 dollars and we want to use a total amount of 18 dollars to pay we should use at least a coin with value 4 (18-15+1) or else at some point in the process of paying the amount we have given to the machine surpasses 15 and it won't receive any more coins.
So what I have done so far is this
A //amount we should pay
D //value of the coin with max value among all present coin types
for value_to_change in A to A+D-1
clear the memoized table for maximal_change
r = maximal_change(value_to_change,0,0)
d = minimal_change(value_to_change-A)
ans = max( ans, r-d )
max_coin // the maximum value of the coin we have used so far
maximal_change( value_to_change, index_of_coin_type, max_coin )
if we have computed (value_to_change, index_of_coin_type)
return the computed value
if (it is the last coin type) AND (max_coin > A-value_to_change)
if value_to_change % value[index_of_coin_type]==0
return value_to_change / value[index_of_coin_type]
else
return we cant change this value with this coin // -1
for i in [0, number_of_available_coins_with_this_type]
n = maximal_change( value_to_change - i*value_of_this_coin_type,
index_of_coin_type+1,
max(max_coin, value_of_this_coin_type) )
if n != -1 // we can change the value
result = max(n+i, result)
dp[value_to_change][index_of_coin_type] = result;
return result
now my problem is my solution is slower than what is expected and I think it is because that I clear the memoized table for every value to change. This is only because in each value to change we are required to use a coin with value at least (value_to_change-A+1).
problem: http://sharecode.io/contests/problem/61839754/C21
my implementation: http://paste.ubuntu.com/13247235/9
Edit:
For improving the performance I came up with a fill table algorithm as follows:
I define an array M that stores the maximum number of coins we can use to make that value. For example if M[3]=5 it means that we can change amount 3 with at most 5 coins. Also I define an auxiliary array for each type of coin that store how many coins should I use to make some amount. For example if aux[2][5]=1 it means that for changing value 5 we need to use 1 coin of type 2.
First we initialize both arrays to -1 and initialize M[0]=0 because we can make value 0 by using 0 coins. Now we sort the coins according to their value. For each type of coin we fill the array like this:
// k number of coin types
// coin array is sorted by value of the coin type
for i in [0,k-1]
for value in [coin[i].value to A + coin[i].value]
if M[value-coin[i].value] == -1
continue
if aux[i][value-coin[i].value] >= coin[i].number
continue
if M[value-coin[i].value]+1 > M[value]
M[value] = M[value-coin[i].value]+1
aux[i][value] = aux[i][value-coin[i].value]+1
Now I am not getting time limit for this but I am getting wrong answer.
my implementation: paste.ubuntu.com/13260401/
Now I wonder if anybody could give me a test case which my algorithm fails to provide an optimal answer to it.
created
last reply
- 1
reply
- 2.1k
views
- 2
users
- 2
links