具体来说,问题是:
给定面值数组
这是我的解决方案:
但是它通常不起作用。
我的问题在于,例如在这种情况下:
但实际上应该是:
给定面值数组
coins[]
、每种硬币的限制数组limits[]
和数字amount
,返回获取amount
所需的最小硬币数,如果不可能,则返回null。此外,还需要在解决方案中填充数组change
,其中包含每种硬币使用的数量。这是我的解决方案:
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;
}
但是它通常不起作用。
我的问题在于,例如在这种情况下:
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 }
最佳解决方案是:
change = new int[] { 1, 0, 1, 1, 1, 1, 0, 0, 0 }
我的算法返回结果为null
。换句话说,在某些情况下,我必须使用次优解决方案,而不是最优解决方案,因此算法失败了,最终我没有足够的硬币。
因此,在这个例子中,我的算法在以下步骤中犯了错误:
minCoins[132] = (9 + 123) // 2 coins
但实际上应该是:
minCoins[132] = (2 + 65 + 35 + 30) // 4 coins
因为这样我可以使用9并获得141。
我已经花了几个星期回到这个问题上,但我仍然无法解决它。我看过这个和其他网站上类似问题的许多解决方案,但它们都没有帮助到我。