Algorithm to calculate the number of combinations to form 100

前端 未结 5 443
说谎
说谎 2020-12-08 23:13

I am struck in a tricky situation where I need to calculate the number of combinations to form 100 based on different factors.

Those are

  • Number of combin
5条回答
  •  感情败类
    2020-12-09 00:00

    Is the distance between all the additive factors, or between each of them? For example, with 3-10-20, is [20-40-60] a valid answer? I'll assume the latter, but the solution below can be modified pretty trivially to work for the former.

    Anyway, the way to go is to start with the most extreme answer (of one sort) that you can manage, and then walk the answers along until you get to the other most extreme.

    Let's try to place numbers as low as possible except for the last one, which will be as high as possible (given that the others are low). Let the common divisor be d and divide 100 by it, so we have S = 100/d. This quantizes our problem nicely. Now we have our constraint that spacing is at most s, except we will convert that to a number of quantized steps, n = s/d. Now assume we have M samples, i1...iM and write the constraints:

    i1 + i2 + i3 + ... + iM = S
    0 <= i1 <= n
    0 <= i2 <= n
    . . .
    0 <= iM <= n
    i1 <= i2
    i2 <= i3
    . . .
    i(M-1) <= iM
    

    We can solve the first equation to get iM given the others.

    Now, if we make everything as similar as possible:

    i1 = i2 = ... = iM = I
    M*I = S
    I = S/M
    

    Very good--we've got our starting point! (If I is a fraction, make the first few I and the remainder I+1.) Now we just try to walk each variable down in turn:

    for (i1 = I-1 by -1 until criteria fails)
      sum needs to add to S-i1
      i2 >= i1
      i2 <= i1 +n
      solve the same problem for M-1 numbers adding to S-i1
      (while obeying the above constraint on i2)
    

    Well, look here--we've got a recursive algorithm! We just walk through and read off the answers.

    Of course, we could walk i1 up instead of down. If you need to print off the answers, may as well do that. If you just need to count them, note that counting up is symmetric, so just double the answer you get from counting down. (You'll also have a correction factor if not all values started the same--if some were I and some were I+1, you need to take that into account, which I won't do here.)


    Edit: If the range is what every value has to fit within, instead of all the

    0 <= i1 <= n
    

    conditions, you have

    max(i1,i2,...,iM) - min(i1,i2,...,iM) <= n
    

    But this gives the same recursive condition, except that we pass along the max and min of those items we've already selected to throw into the mix, instead of adding a constraint on i2 (or whichever other variable's turn it is).

提交回复
热议问题