To be specific, the problem is:
Given array of denominations coins[], array of limit for each coins limits[] and number amount, return minimum number of coins needed, to get the amount, or if it's not possible return null. Additionally fill array change with number of each coin used in the solution.
This is my solution:
public static int? Dynamic(int amount, int[] coins, int[] limits, out int[] change)
{
int[] minCoins = new int[amount + 1];
int[,] coinsUsedToAmount = new int[coins.Length, amount + 1];
minCoins[0] = 1;
for (int j = 0; j < amount; ++j)
{
if (minCoins[j] == 0)
{
continue;
}
for (int i = 0; i < coins.Length; ++i)
{
if (coinsUsedToAmount[i, j] >= limits[i])
{
continue;
}
int currAmount = j + coins[i];
if (currAmount <= amount
&& (minCoins[currAmount] == 0
|| minCoins[currAmount] > minCoins[j] + 1))
{
minCoins[currAmount] = minCoins[j] + 1;
for (int k = 0; k < coins.Length; ++k)
{
coinsUsedToAmount[k, currAmount] = coinsUsedToAmount[k, j];
}
coinsUsedToAmount[i, currAmount] += 1;
}
}
}
if (minCoins[amount] == 0)
{
change = null;
return null;
}
change = new int[coins.Length];
for(int i = 0; i < coins.Length; ++i)
{
change[i] = coinsUsedToAmount[i, amount];
}
return minCoins[amount] - 1;
}
But it doesn't work in general.
My issue is that for example in such case:
amount = 141,
coins = new int[] { 2, 137, 65, 35, 30, 9, 123, 81, 71 }
limits = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 }
Optimal solution is:
change = new int[] { 1, 0, 1, 1, 1, 1, 0, 0, 0 }
And my algorithm gives null as the result. In the other words it fails, whenever on some way up I would have to use less optimal solution than it's possible, and then, at the end, I don't have necessary coins.
So, in this example my algorithm makes a mistake in following step:
minCoins[132] = (9 + 123) // 2 coins
But it should be:
minCoins[132] = (2 + 65 + 35 + 30) // 4 coins
because then I can use 9 and have 141.
I have been coming back to this problem for a few weeks now and I still can't solve it. I had seen numerous solutions to similar problems on this and other sites, but none of them helped me.