具体而言,问题是:
给定面额数组<代码>硬币[],每个硬币的限制数组<代码>限制[]和数量<代码>金额,返回所需的最小硬币数量,以获取<代码>金额,或者如果不可能,返回空值。另外,用溶液中使用的每个硬币的数量填充数组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。
我已经回到这个问题上几个星期了,但我仍然无法解决它。我在这个网站和其他网站上看到了许多类似问题的解决方案,但没有一个对我有帮助。
我的朋友帮我解决了这个问题。我们的想法是从数量
到0
,并尽可能使用每种硬币的所有面值-这样我们就不会在开始时使用某些硬币,也就不可能使用它们来表示金额。
/// <summary>
/// Method used to resolve minimum change coin problem
/// with constraints on the number of coins of each type.
/// </summary>
/// <param name="amount">Amount of change to make, e.g. 13</param>
/// <param name="coins">Available types of coins, e.g. {1, 2, 3, 5}</param>
/// <param name="limits">Number of available coins of specific type, e.g. {1, 5, 3, 2}</param>
/// <param name="change">Number of coins of each type used to make the change, e.g. {0, 0, 1, 2}</param>
/// <returns>
/// Minimal number of coins needed to make the change
/// (equal to sum of change array entries), e.g. 3
/// </returns>
/// <remarks>
/// coins[i] - nominal value of the coin of i-th type
/// limits[i] - number of available coins of i-th type (denomination)
/// change[i] - number of coins of i-th type used in the solution
///
/// If available `coins` and `limits` does not allow to make provided `amount` of change
/// then `change` should be set to `null`, and method should also return `null`.
///
/// Tips/requirements:
/// The size of work memory of the algorithm should (must) be
/// proportional to the value of product: `amount*(coins.Length)`
/// (that is O(amount*(coins.Length))
/// </remarks>
public static int? Dynamic(int amount, int[] coins, int[] limits, out int[] change)
{
int[][] coinsUsed = new int[amount + 1][];
for (int i = 0; i <= amount; ++i)
{
coinsUsed[i] = new int[coins.Length];
}
int[] minCoins = new int[amount + 1];
for (int i = 1; i <= amount; ++i)
{
minCoins[i] = int.MaxValue - 1;
}
int[] limitsCopy = new int[limits.Length];
limits.CopyTo(limitsCopy, 0);
for (int i = 0; i < coins.Length; ++i)
{
while (limitsCopy[i] > 0)
{
for (int j = amount; j >= 0; --j)
{
int currAmount = j + coins[i];
if (currAmount <= amount)
{
if (minCoins[currAmount] > minCoins[j] + 1)
{
minCoins[currAmount] = minCoins[j] + 1;
coinsUsed[j].CopyTo(coinsUsed[currAmount], 0);
coinsUsed[currAmount][i] += 1;
}
}
}
limitsCopy[i] -= 1;
}
}
if (minCoins[amount] == int.MaxValue - 1)
{
change = null;
return null;
}
change = coinsUsed[amount];
return minCoins[amount];
}
所以我对编码不熟悉,我得到了一个任务,我需要做一个程序,用四分之一、一角、五分和一美分给不到一美元的零钱。然而,作业希望程序打印所需的最低硬币数量(例如,如果我输入58美分,那么输出应该是“2个25美分,1个镍和3个便士”,而不是“2个25美分,0个10美分,1个镍和3个便士”。本质上,如果没有某种硬币,那么程序就不应该打印它)。我一直在想如何制作它,这样程序就不会打印任何不必要的硬币。 这就是我
动态规划变更问题(有限硬币)。我正在尝试创建一个以以下内容作为输入的程序: 输出: 输出应该是大小为1的数组,其中每个单元格代表我们需要改变单元格索引量的最佳硬币数。 假设数组的单元格位于index: 5,内容为2。这意味着为了给出5(INDEX)的变化,您需要2(单元格的内容)硬币(最佳解决方案)。 基本上,我需要这个视频的第一个数组的输出(C[p])。这与有限硬币的大区别是完全相同的问题。链接
问题:https://leetcode.com/problems/coin-change/ 解决方案:https://repl.it/@Stylebender/HatefulAliceBlueTransverse#index.js 我理解从“按钮式”构建dp阵列解决方案的一般概念流程,但我只是想知道关于第10行: dp[i]=数学。最小值(dp[i],1 dp[i-硬币[j]]; 当你选择当前的第
我们得到了一套面额和总额。 每种面额的无限硬币都可以买到 所有面额都是5的幂 我们必须找到总数所需的最低硬币数量。 我想知道解决方案背后的逻辑。提前感谢。
我有以下问题: 给定一个目标大小N和一些随机生成的硬币的一些面额,这些硬币存储在数组面额[]中,使用动态规划检查是否存在一个最优解决方案,该方案将使用最少的硬币填充整个目标。 这是硬币兑换问题的一个典型例子,但与现实生活中的货币不同,在现实生活中,每种面额都是经过仔细挑选的,因此可以匹配任何目标。事实并非如此。 我熟悉硬币兑换问题中使用的算法,以及如何构造一个动态规划数组来找到解决方案,但我首先如
我正在尝试打印最小数量的硬币来进行更改,如果不可能,请打印-1 在这段代码中,变量int[]c(硬币数组)有面额,我可以用它来计算总金额。 INT总有总和,我需要拿出使用硬币(无限供应) 对于Sum:4759和Array:{3190836},正确的输出是:59,我的输出是:60 代码中有什么错误? 下面是我的递归解决方案,尝试在DP解决方案中应用相同的逻辑。这里的逻辑似乎也有问题。对于相同的输入,