Sum of multiplication of all combination of m element from an array of n elements

后端 未结 3 920
走了就别回头了
走了就别回头了 2020-12-03 13:06

Suppose I have an array {1, 2, 5, 4} and m = 3. I need to find:

1*2*5 + 1*2*4 + 1*5*4 + 2*5*4

i.e Sum of multipli

相关标签:
3条回答
  • 2020-12-03 13:38

    I came up with the same problem. I found the solution via Vieta's Algorithm as well. I tweaked the algorithm not the calculate the coefficient of the polynomial which are not needed. The complexity is O(N*M). I looked into DFTs and FFTs but if M is small enough, this method will be even faster than Fast Fourier Transformation algorithms. This is java btw.

    public BigInteger sumOfCombMult(Integer[] roots, int M)
    {
        if (roots.length < M)
        {
            throw new IllegalArgumentException("size of roots cannot be smaller than M");
        }
    
        BigInteger[] R = new BigInteger[roots.length];
    
        for (int i = 0; i < roots.length; i++)
        {
            R[i] = BigInteger.valueOf(roots[i]);
        }
    
        BigInteger[] coeffs = new BigInteger[roots.length + 1];
    
        coeffs[0] = BigInteger.valueOf(roots[0]);
    
        int lb = 0;
    
        for (int i = 1; i < roots.length; i++)
        {
            lb = Math.max(i - M, 0);
    
            coeffs[i] = R[i].add(coeffs[i - 1]);
    
            for (int j = i - 1; j > lb; j--)
            {
                coeffs[j] = R[i].multiply(coeffs[j]).add(coeffs[j - 1]);
    
            }
    
            if (lb == 0)
            {
                coeffs[0] = coeffs[0].multiply(R[i]);
            }
        }
    
        return coeffs[roots.length - M];
    }
    
    0 讨论(0)
  • 2020-12-03 13:39

    This problem is equivalent to calculation of Mth coefficient of polynom with given roots (Vieta's theorem). Adapted algorithm in Delphi (O(N) memory and O(N^2) time):

     function CalcMultiComb(const A: array of Integer; const M: Integer): Integer;
      var
        i, k, N: Integer;
        Coeff: TArray<Integer>;
      begin
        N := Length(A);
        if (N = 0) or (M > N) then
          Exit;
        SetLength(Coeff, N + 1);
    
        Coeff[0] := -A[0];
        Coeff[1] := 1;
        for k := 2 to N do begin
          Coeff[k] := 1;
          for i := k - 2 downto 0 do
            Coeff[i + 1] := Coeff[i] - A[k-1] * Coeff[i + 1];
          Coeff[0] := -A[k-1] * Coeff[0];
        end;
    
        Result := Coeff[N - M];
        if Odd(N - M) then
          Result := - Result;
      end;
    

    calls CalcMultiComb([1, 2, 3, 4], M) with M=1..4 give results 10, 35, 50, 24

    0 讨论(0)
  • 2020-12-03 13:44

    I have a Dynamic programming solution in my mind, just want to share. Time complexity is O(k*n^2) with n is total number.

    The idea is, we start to fill in each position from 0 to k -1. So if we assume at position ith, the number to be filled for this position is a, so the sum of all combination start with a will be a times the total of all combination from position (i + 1)th starting with (a + 1)

    Note: I have updated the solution, so it can work with any array data, My language is Java, so you can notice that the index for array is 0 based, which start from 0 to n-1.

    public int cal(int n, int k , int[]data){
       int [][] dp = new int[k][n + 1];
       for(int i = 1; i <= n; i++){
           dp[k - 1][i] = data[i - 1];
       }
       for(int i = k - 2; i >= 0; i--){
           for(int j = 1 ; j <= n; j++){
               for(int m = j + 1 ; m <= n; m++){
                   dp[i][j] += data[j - 1]*dp[i + 1][m];
               }
           }
       }
       int total = 0;
       for(int i = 1; i <= n; i++){
           total += dp[0][i];
       }
       return total;
    }
    
    0 讨论(0)
提交回复
热议问题