当前位置: 首页 > 知识库问答 >
问题:

当订单很重要时,如何解决硬币兑换任务?

牛兴安
2023-03-14

正如我在这里发现的,

硬币兑换是指使用给定的一组面额d_1,找到对特定金额的美分、n进行兑换的方法的数量。。。。这是整数分割的一般情况,可以用动态规划来求解。

这个问题通常被问到:如果我们想改变N美分,并且我们有无限的S={S_1,S_2,......,S_m}价值的硬币,我们有多少种方法可以改变?(为了简单起见,顺序并不重要。)

我试过这个,效果很好。所以,当不同硬币的顺序确实重要时,我如何修改它来找到所有可能的硬币组合。

即:以前

例如,对于N=4,S={1,2,3},有四个解:{1,1,1,1},{1,1,2},{2,2},{1,3}。

现在:

对于N=4, S={1,2,3},有7个解:{1,1,1,1},{1,1,2},{1,2,1},{2,2},{1,3},{3,1}

在这里{1,1,1,1}即使可以按不同的顺序选择四个'1',也必须将其视为一个最终组合。而不是考虑到四枚硬币是不同的。因此,实际上,不同硬币的顺序必须不同,才能将其作为单独的组合来计算。

例如:{1,1,3}不会假设{1_a,1_b,3_a}是一个组合,{1_b,1_a,3_a}是另一个具有不同顺序的组合。

共有3个答案

缪晋
2023-03-14

当前的递归实现非常简单。它只传递剩余值和可能面额的索引。如果在n==0时传递了一个面额数组,则可以添加另一个检查以查看是否已经有了该组合。如果返回0,则返回1。

这是一个动态的解决方案,需要比其他解决方案多得多的内存,但它会为您找到答案。

func count(n, m, p[])
//regular if checks with additional nested if in (n == 0)
return count( n, m - 1, p[] ) + count( n - S[m], 0, p[] + S[m] )

在这个伪代码中,p[]S[m]只意味着将S[m]添加到p[]中的下一个可用位置

编辑:

忘记加了你下潜的时候需要重置m

// n is remaining value
// m is index of S array
// p[] is array of coins used
// solutions[] is an array of p[] arrays
func count( n, m, p[]) {
  if n == 0
    if (p[] not in solutions[]){
      solutions[].add(p[])
      return 1
    }else{
      return 0
    }
  if n < 0
    return 0
  if m <= 0 and n >= 1
    return 0
  return count(n, m - 1, p[]) + count( n - S[m], 0, p[].add(S[m]))
}

每次向可能的集合添加硬币时,从空数组p[]开始,将该值追加到数组。当你找到解决方案的时候,你会看到它是否独一无二。如果是这样,你把它添加到计数中,否则你会忽略它。因为m每次复位都会遍历所有可能的排列。

齐航
2023-03-14

如果你在参考的维基百科页面中提到“动态规划”算法,我想你可以改变

table[ i, j ] = table[ i - S_j, j ] + table[ i, j - 1 ]

table[ i, j ] = table[ i - S_j, m ] + table[ i, j - 1 ]

但是我还不是100%确定。关键是在最初的问题中,当你检查硬币Sj时,你想在数量为i-Sj但只有硬币通过Sj,这样就不会得到前一个序列的排列。通过将其更改为table[i-S_j, m],您可以计算排列。

编辑:进一步研究后,我认为这是正确的,但与亨利的答案相当,后者简单得多。这个版本的问题(计算所有排列)不需要像原始数组那样将值存储在二维数组中。

潘宝
2023-03-14

仅计算解决方案的数量比全部枚举要省力得多。

让我们以S={1,2,3}为例,调用f(n)数量n的解的数量。

然后我们有:

f(n)=0如果n

F(0)=1

f(n)=f(n-1)f(n-2)f(n-3)如果n

编写执行这些计算的程序并不太困难。你可以从低数字开始,然后逐步向上:

f(0) = 1
f(1) = 1
f(2) = 2
f(3) = 4
f(4) = 7
f(5) = 13
...

对于这个特殊的S,每个数字都是前面三个数字的和。

如何得出这个公式?我再次以特定的集合S={1,2,3}为例,一般情况同样简单。要计算n的解决方案数,请查看第一个元素。它可以是1、2或3。如果为1,则有f(n-1)种方式来排列剩余的元素。如果为2,则剩余元素有f(n-2)种方式,最后如果为3,则剩余元素有f(n-3)种方式。因此,总数必须是三者之和。

 类似资料:
  • 请在下面的链接中查看最小硬币兑换问题的解决方案 http://techieme.in/minimum-number-of-coins/ 在这里,作者假设 面额数组按升序排列。 我的问题是,为什么面额数组的顺序很重要。 下面的链接中也采用了类似的假设(请注意,作者在这里解决的是硬币兑换的不同方式,而不是最小的硬币兑换) http://www.algorithmist.com/index.php/Co

  • 我在理解动态规划中的硬币兑换问题时遇到了一个小问题。简单地说,我必须用最少数量的硬币来兑换一笔钱。 我有n种面值为1=v1的硬币

  • 我有一个练习: 您将获得不同面额的硬币和总金额。请编写一个函数来计算您需要的最少数量的硬币,以弥补该金额。如果硬币的任何组合都无法弥补该金额,请返回-1 例1: 我还谷歌了一个这样的解决方案: 我知道它是关于DP的,但是,我对它很困惑,比如,的含义是什么,为什么要添加,为什么要添加,为什么要添加1? 有人能用简单的英语指出出路吗?

  • 给定一个值N,如果我们想换N美分,并且我们有无限量的S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序无关紧要。 例如,对于N=4和S={1,2,3},有四种解:{1,1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是4。对于N=10和S={2,5,3,6},有五个解:{2,2,2,2},{2,2,3,3},{2,2,6},{2,3,5}和{5,5}。所以

  • 以人民币的硬币为例,假设硬币数量足够多。要求将一定数额的钱兑换成硬币。要求兑换硬币数量最少。 思路说明: 这是用贪婪算法的典型应用。在本例中用python来实现,主要思想是将货币金额除以某硬币单位,然后去整数,即为该硬币的个数;余数则做为向下循环计算的货币金额。 这个算法的问题在于,得出来的结果不一定是最有结果。比如,硬币单位是[1,4,6],如果将8兑换成硬币,按照硬币数量最少原则,应该兑换成为

  • 我编写的代码使用动态规划解决了基本的硬币兑换问题,并给出了进行兑换所需的最小硬币数量。但是我想把每个硬币的数量存储在最小的数字里。 我试图做的是初始化数组,就像散列一样,只要找到,它就会增加的数量,即。但这并不是我想要的方式,因为它每次发现对应于时都会添加硬币。因此,在最终答案中,数字不是硬币的最终计数。 代码如下: