【问题标题】:Algorithm for determining number of possible combinations确定可能组合数量的算法
【发布时间】:2012-06-16 05:05:39
【问题描述】:

我需要为一个给定的问题编写一个算法:你有无限的便士、五分钱、一角钱和四分之一。编写一个类方法,输出所有硬币组合,使总和为 99 美分。

这似乎是一个排列 nPr 问题。有什么算法吗?

问候, 普里扬克

【问题讨论】:

标签: algorithm permutation


【解决方案1】:

我认为使用面额表递归最容易解决这个问题

{5000, 2000, ... 1} // 50 美元兑换一便士

你会开始:

WaysToMakeChange(10000, 0) // ie. $100...highest denomination index is 0 ($50)

WaysToMakeChange(amount, maxdenomindex) would calculate using 0 or more of the maxdenom
the recurance is something like
WaysToMakeChange(amount - usedbymaxdenom, maxdenomindex - 1)

我对此进行了编程,并且可以通过多种方式对其进行优化:

1) 多线程

2) 缓存。这个非常重要。算法工作方式的 B/c,WaysToMakeChange(m,n) 将使用相同的初始值多次调用: 例如。可以通过以下方式更改 100 美元: 1 $50 + 0 $20's + 0 $10's + 以最高货币 $5 达到 $50 美元的方式(即 WaysToMakeChange(5000, index for $5) 0 $50 + 2 $20's + 1 $10's + 以最高货币 $5 达到 $50 美元的方式(即 WaysToMakeChange(5000, index for $5) 显然 WaysToMakeChange(5000, index for $5) 可以被缓存,这样后续调用就不需要了

3) 短路最低递归。 假设 static const int denom[] = {5000, 2000, 1000, 500, 200, 100, 50, 25, 10, 5, 1};

WaysToMakeChange(int total, int coinIndex) 的第一个测试应该是这样的: if(硬币[_countof(coins)-1] == 1 && coinIndex == _countof(coins) - 2){ 返回总数/硬币[_countof(coins)-2] + 1; }

这是什么意思?好吧,如果你的最低面额是 1,那么你只需要走到第二低的面额(比如镍)。然后剩下 1+ 总/第二低的面额。例如: 49c -> 5 镍币 + 4 便士。 4 个镍币 + 9 个便士....49 个便士 = 1+ 总数/剩下的第二个最低面额

【讨论】:

    【解决方案2】:

    最简单的方法可能是花几分钟时间思考这个问题。有一种相对不错的递归算法,可以巧妙地用于记忆或重新加工成动态编程解决方案。

    【讨论】:

    • +1:虽然我认为现在最简单的方法似乎是“问 SO,有人会为我做我的工作”,但您建议使用更好的方法。
    • @HighPerformanceMark:是的,我试图给出一个答案,虽然有帮助,但并不能说明全部内容。如果我确信这不是家庭作业(或者是家庭作业,并给出了一些思考的证据),我什至可能会提供更多细节。
    【解决方案3】:

    这个问题是经典的动态规划问题。你可以在这里阅读它

    http://www.algorithmist.com/index.php/Coin_Change

    python代码是:

    def count( n, m ):
        if n == 0:
            return 1
        if n < 0:
            return 0
        if m <= 0 and n >= 1:
            return 0
    
        return count( n, m - 1 ) + count( n - S[m], m )
    

    这里 S[m] 给出面额的值,S 是面额的排序数组

    【讨论】:

      【解决方案4】:

      这个问题似乎是diophantine equation,即对于a*x + b*y + ... = n,找到一个解决方案,其中所有字母都是整数。最简单但不是最优雅的解决方案是迭代解决方案(在 python 中显示,注意我跳过变量 l 因为它类似于数字 1):

      dioph_combinations = list()
      for i in range(0, 99, 25):
          for j in range(0, 99-i, 10):
              for k in range(0, 99-i-j, 5):
                  for m in range(0, 99-i-j-k, 1): 
                      if i + j + k + m == 99:
                          dioph_combinations.append( (i/25, j/10, k/5, m) )
      

      结果列表 dioph_combinations 将包含可能的组合。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 2020-09-08
      • 2011-08-19
      • 1970-01-01
      • 2018-03-15
      • 2012-06-12
      • 1970-01-01
      相关资源
      最近更新 更多