【问题标题】:Sum of combinations of numbers数字组合的总和
【发布时间】:2017-01-01 01:19:43
【问题描述】:

我想以最快的方式解决一个数学问题。 我有一组介于 1 到 n 之间的自然数,例如 {1,2,3,4,n=5},我想计算如下公式:

s = 1*2*3*4+1*2*3*5+1*2*4*5+1*3*4*5+2*3*4*5

如您所见,和中的每个元素都是集合中 n-1 个数字的乘积。例如,在 (1*2*3*4) 中,5 被排除在外,在 (1*2*3*5) 中,4 被排除在外。我知道有些乘法是重复的,例如 (1*2) 在 3 次乘法中重复。我怎样才能用最少的乘法来解决这个问题。

抱歉英语不好。 谢谢。

【问题讨论】:

  • 这是一个编程问题吗?你试过什么?除法是算作乘法还是以其他方式? (我能想到几种使用一个或多个除法或倒数的方法。)那么加法呢?每个乘法都可以用多个加法代替,这样就不用乘法了。
  • 我不想使用除法。只有乘法和求和。这是我想要解决的更大问题的一部分。我尝试在树中构造数字,但找不到可以使用重复乘法的良好结构。
  • 您还没有回答关于用加法替换所有乘法的问题。另外,您的目标是尽量减少时间(如您在第一句话中所说)或乘法(如您在几乎最后一句话中所说)或其他什么?
  • 我想在计算机上运行一个解决这个问题的代码。所以我想减少乘法并使用总和的数量,但我不认为用总和替换所有乘法是一种更快的方法。因为我认为这样我们需要更多的 CPU 周期来解决它。
  • 我真的很想这样做,但我需要 15 个或更多我没有的声望。谢谢大家帮助我。

标签: math numbers combinations discrete-mathematics


【解决方案1】:

这是一种不会“作弊”的方法,即用重复加法或除法代替乘法。这个想法是用

替换你的表达

1*2*3*4 + 5*(1*2*3 + 4*(1*2 + 3*(1 + 2)))

这对数字 1 到 5 使用了 9 次乘法。一般来说,我认为乘法计数会比第 (n-1) 个三角形数 n * (n - 1) / 2 - 1 少一。这里是存储中间阶乘值以将乘法次数减少到仅 6 次的 Python 代码,或者通常为 2 * n - 4,并且加法计数相同(但其中一半只是加 1):

def f(n):
    fact = 1
    term = 2
    sum = 3
    for j in range(2, n):
        fact *= j
        term = (j + 1) * sum
        sum = fact + term
    return sum

找出哪种算法最快的唯一方法是用一种语言对所有算法进行编码,并使用计时器运行每个算法。

【讨论】:

    【解决方案2】:

    以下将是最直接的答案。

    def f(n):
        result = 0
        nList = [i+1 for i in range(n)]
        for i in range(len(nList)):
            result += reduce(lambda x, y: x*y,(nList[:i]+nList[i+1:]))
    return result
    

    演练 - 使用 reduce 函数将所有长度为 n-1 的列表相乘并添加到变量结果中。

    【讨论】:

    • 我知道这种方法,但是有没有一种方法可以让我使用复制乘法来更快地解决它?
    • @Bazinevis 你的意思是递归吗?
    【解决方案3】:

    如果你只是想尽量减少乘法的次数,你可以用加法代替所有的乘法,像这样:

    // Compute 1*2*…*n
    mult_all(n):
        if n = 1
            return 1
        res = 0
        // by adding 1*2*…*(n-1) an entirety of n times
        for i = 1 to n do
            res += mult_all(n-1)
        return res
    
    // Compute sum of 1*2*…*(i-1)*(i+1)*…*n
    sum_of_mult_all_but_one(n):
        if n = 1
            return 0
        // by computing 1*2*…*(n-1) + (sum 1*2*…*(i-1)*(i+1)*…*(n-1))*n
        res = mult_all(n-1)
        for i = 1 to n do
            res += sum_of_mult_all_but_one(n-1)
        return res
    

    【讨论】:

      【解决方案4】:

      这是一个适用于 javascript 的答案。这不是最快的方法,因为它没有经过优化,但是如果您只想找到答案,它应该可以工作。

      function combo(n){
      var mult = 1;
      var sum = 0;
      for (var i = 1; i <= n; i++){
          mult = 1;
          for (var j = 1; j<= n; j++){
              if(j != i){
                  mult = mult*j;
              }
          }
          sum += mult;
      }
      return (sum);
      }
      
      alert(combo(n));
      

      【讨论】:

      • 你是对的。感谢您指出这一点。我会改的。
      猜你喜欢
      • 2016-09-24
      • 1970-01-01
      • 2020-08-10
      • 2012-03-11
      • 1970-01-01
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多