I think that the fact that the numbers should have different positions is a red herring. You can use the inclusion-exclusion principle to count the number of all positions (i, j, k, l, m), where x [i] + x [j] + x [k] + x [l] + x [m] = S and i, j, k, l, m are different:
sums with i!=j,i!=k,i!=l...,l!=m = all sums - sums with i=j - ... - sums with l=m + sums with i=j and j=k + ... + sums with k=l and l=m - ... + sums with i=j=k=l=m
The calculation of the sums to the right, except for the first, is performed in O (N ^ 2 log N). For example, to find the number of positions (i, i, k, l, m) such that x [i] + x [i] + x [k] + x [l] + x [m] = S you can create sorted arrays with sums {2a + b} and {c + d} and check whether they have elements x, y such that x + y = S.
Basic algorithm
So, it is enough to calculate how many of them are (i, j, k, l, m), where x[i]+x[j]+x[k]+x[l]+x[m]=S and i , j, k, l, m are not necessarily different. Basically, you can use the Moron solution this way:
Create a sorted array of sums {a + b: a, b - numbers from the array}; group equal elements into one, remembering the counter. For example, for the array [1,1,3] you get nine sums [2,2,2,2,4,4,4,4,4,6] of form a + b. Then you group the same elements, remembering the calculations: [(2,4), (4,4), (6,1)]. This step is O (N ^ 2 log N).
For each e, count how many pairs there are pairs of elements that sum with Se. As in Moron’s decision, you have two pointers: one goes to the right, one goes to the left. If the amount is too low, move the first pointer, increasing the amount; if the amount is too high, move the second pointer to decrease it.
Assume the amount is correct. This means that one points to (a, x) and the second to (b, y), where a + b = Se. Increase the counter by x * y and move both pointers (you can only move one pointer, but there will be no match in the next step, and the second pointer will then be moved.).
For example, for the array [(2,4), (4,4), (6,1)] and Se = 8, the first pointer points to (2,4), and the second to (6,1). Since 2 + 6 = 8, you add 4 and move both pointers. Now they both point to (4.4), so you increase the counter by 16. Do not stop! The pointers go to each other, and you first get at (6.1), a second at (2.4), increase the counter by 4.
So, at the end there are 4 + 16 + 4 = 24 ways to get 8 as the sum of 4 elements from [1,1,3]:
>>> len([k for k in itertools.product([1,1,3],repeat=4) if sum(k) == 8]) 24 Prelude Control.Monad> length [k | k <- replicateM 4 [1,1,3], sum k == 8] 24
Repeating this for each e, you will get the number of ways to get S as the sum of 5 elements.
For [1,1,1,1,1,1] and Se = 4 the array of sums will be [(2,25)], and you will get that there are 625 ways to get the sum of 4.
For each e, this step is linear in size of the array (so O (N 2 )), so the loop takes O (N 3 ).
About inclusion-exception :
Call the five-digit (i, j, k, l, m) “correct” if x [i] + x [j] + x [k] + x [l] + x [m] = S. The goal is to calculate the number of proper fivefold (i, j, k, l, m), where i, j, k, l, m are pairwise different. The main algorithm can calculate in O (N ^ 3) how many of them have the correct five-line numbers, which are not necessarily separate components. The rest is to count these "wrong" tuples.
Consider the subsets of eigenfold fivefold numbers
A xy = {(i, j, k, l, m): the indices at the xth and yth places are the same}
For example, A 24 is a set of regular five-fold (i, j, k, l, m), where j = l.
A set of incorrect five-fold numbers:
A 12 ∪ A 13 ∪ ... ∪ A 45
Calculation of its power using inclusion-exclusion:
| A 12 ∪ A 13 ∪ ... ∪ A 45 | = | A 12 | + | A 13 | + ... + | A 45 | - | A 12 ∩ A 23 | -... - | A 34 ∩ A 45 | + ... + | A 12 ∩ A 23 ∩ ... ∩ A 35 ∩ A 45 |
There are 2 10 = 1024 terms. But a lot of power is the same.
The only thing you should consider:
- X 1 = | A 12 | - fivefold with i = j
- X 2 = | A 12 ∩ A 23 | - fivefold with i = j = k
- X 3 = | A 12 ∩ A 23 ∩ A 34 | - fivefold with i = j = k = l
- X 4 = | A 12 ∩ A 23 ∩ A 34 ∩ A 45sub> | - five times with i = j = k = l = m
- X 5 = | A 12 ∩ A 34 | - fivefold with i = j, k = l
- X 6 = | A 12 ∩ A 23 ∩ A 45 | - fivefold with i = j = k, l = m
You can observe, rearranging, all other sets are presented here. For example, A 24 has the same power as A 12 .
The power counting of these 6 sets is pretty simple. For the first you create arrays {2a + b} and {c + d} and count how many common elements; for others there are only 3 or less free variables, so even a simple loop will give you O (N ^ 3).
To simplify the amount, I wrote the following Haskell program:
import Control.Monad import Data.List import qualified Data.Map as Map -- Take equivalence relation, like [(1,2),(2,3)] and return its partition, like [3,1,1] f xs = sort $ map length $ foldr f (map return [1..5]) xs where f (x,y) a = let [v1] = filter (x `elem`) a [v2] = filter (y `elem`) a in if v1 == v2 then a else (a \\ [v1,v2]) ++ [v1++v2] -- All 1024 subsets of [(1,2),(1,3), ..., (4,5)] subsets = filterM (const [False, True]) [(i,j) | i <- [1..5], j <- [i+1..5]] res = Map.fromListWith (+) $ map (\k -> (fk, (-1)^(length k))) subsets *Main> res Loading package array-0.3.0.1 ... linking ... done. Loading package containers-0.3.0.0 ... linking ... done. fromList [([1,1,1,1,1],1),([1,1,1,2],-10),([1,1,3],20),([1,2,2],15),([1,4],-30),([2,3],-20),([5],24)]
which means the formula
all subsets are 10X 1 + 20X 2 - 30X 3 + 24X 4 + 15X 5 - 20X 6 .
Check:
How many of them have five lines in [0,0,0, ..., 0], adding up to 0? One way to calculate this directly, the second way is to use the formula (and not care about different positions):
direct x = x*(x-1)*(x-2)*(x-3)*(x-4) indirect x = x^5 - 10 * x^4 + 20 * x^3 + 15 * x^3 - 30 * x^2 - 20*x^2 + 24*x *Main> direct 100 9034502400 *Main> indirect 100 9034502400
Other notes:
In addition, there is a solution O (a n log a n ): Calculate (x a 1 + ... + x a n ) 5 using FFT, the result is a coefficient at x S. This allows you to use multiple i , but you can subtract polynomials such as (x 2a 1 + ... + x 2a n ) 5 * (x a 1 + ... + x a n ) 3 , etc. in accordance with the principle of inclusion-exclusion.
In some limited computational models, it has been shown to solve this problem O (N ^ 3) time is required.