📜  给定数组的所有可能的K大小子集的乘积总和

📅  最后修改于: 2021-04-29 02:52:04             🧑  作者: Mango

给定的阵列ARRN个非负整数和整数1≤ķ≤N []。任务是找到大小为karr []的所有可能子集的乘积之和。

例子:

天真的方法:生成大小为K的所有可能子集,并找到每个子集的结果乘积。然后对每个子集获得的乘积求和。该解决方案的时间复杂度将是指数级的。

C++
// Program  find the sum of the products of all possible
// subsets of arr[] of size K.
#include 
#include 
using namespace std;
 
// using these variable , to avoid many parameters in a
// recusrive function , which will reduce the speed of
// the program
int K, N;
 
// it returns sum of all the multiplied Subset
int getSum(vector > res)
{
    long long sum = 0, MOD = 1000000007;
 
    for (vector tempList : res) {
 
        long long tempSum = 1;
 
        for (int val : tempList) {
 
            tempSum = (tempSum * val) % MOD;
        }
 
        sum = sum + tempSum;
    }
    // we are doing % operation  , so that our result
    // should not get overflow
    return sum % MOD;
}
 
// Generate all Subsrray with size K
void createAllPossibleSubset(int arr[],
                             vector >& res,
                             vector& temp, int index)
{
    /*
      when we get the required size subset , we
      add into the result list and return
    */
    if (temp.size() == K) {
        res.push_back(temp);
        return;
    }
 
    // otherwise we add current element ,
    // and move forward to add next element in our
    // subset
    for (int i = index; i < N; i++) {
        temp.push_back(arr[i]);
 
        createAllPossibleSubset(arr, res, temp, i + 1);
 
        // removing the last element , for backtracking
        temp.pop_back();
    }
}
 
 
int sumOfProduct(int arr[], int n, int k)
{
    K = k;
    N = n;
 
    // result store all the subset of size K
    vector > res;
    vector temp;
 
    createAllPossibleSubset(arr, res, temp, 0);
 
    return getSum(res);
}
 
 
// Driver code
int main()
{
    int n = 4, k = 2;
    int arr[] = { 1, 2, 3, 4 };
    cout << sumOfProduct(arr, n, k);
    return 0;
}
// This code is contributed by Pradeep Mondal P


Java
// Program  find the sum of the products of all possible
// subsets of arr[] of size K.
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // storing the k value , so that it can be easily
    // accessed
    static int K;
 
    public static int sumOfProduct(int arr[], int n, int k)
    {
        K = k;
 
        // result store all the subset of size K
        ArrayList > res
            = new ArrayList<>();
 
        createAllPossibleSubset(arr, res, new ArrayList<>(),
                                0);
 
        return getSum(res);
    }
 
    // Generate all Subsrray with size K
    static void createAllPossibleSubset(
        int arr[], ArrayList > res,
        ArrayList temp, int index)
    {
        /*
          when we get the required size subset , we
          add into the result list and return
        */
        if (temp.size() == K) {
            res.add(new ArrayList<>(temp));
            return;
        }
 
        // otherwise we add current element ,
        // and move forward to add next element in our
        // subset
        for (int i = index; i < arr.length; i++) {
            temp.add(arr[i]);
 
            createAllPossibleSubset(arr, res, temp, i + 1);
 
            // removing the last element , for backtracking
            temp.remove(temp.size() - 1);
        }
    }
 
    // it returns sum of all the multiplied Subset
    private static int
    getSum(ArrayList > res)
    {
 
        int sum = 0, MOD = 1000000007;
        for (ArrayList tempList : res) {
           
            long tempSum = 1;
            for (int val : tempList) {
               
                tempSum *= val % MOD;
            }
 
            sum += tempSum;
        }
        // we are doing % operation  , so that our result
        // should not get overflow
        return sum % MOD;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 4, k = 2;
        int arr[] = { 1, 2, 3, 4 };
        System.out.println(sumOfProduct(arr, n, k));
    }
}
// This code is Contributed by Pradeep Mondal P


C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the sum of products of
// all the possible k size subsets
int sumOfProduct(int arr[], int n, int k)
{
    // Initialising all the values to 0
    int dp[n + 1][n + 1] = { 0 };
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for (int i = 1; i <= n; i++) {
        dp[1][i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom up manner
    for (int i = 2; i <= k; i++) {
 
        // To store the elements of the current
        // row so that we will be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for (int j = 1; j <= n; j++) {
 
            // We will subtract previously computed value
            // so as to get the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j];
 
            dp[i][j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i][j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4 };
    int n = sizeof(arr) / sizeof(int);
    int k = 2;
 
    cout << sumOfProduct(arr, n, k);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG{
 
// Function to return the sum of products of
// all the possible k size subsets
static int sumOfProduct(int arr[], int n,
                        int k)
{
    int dp[][] = new int[n + 1][n + 1];
     
    // Initialising all the values to 0
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= n; j++)
            dp[i][j] = 0;
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for(int i = 1; i <= n; i++)
    {
        dp[1][i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom
    // up manner
    for(int i = 2; i <= k; i++)
    {
         
        // To store the elements of the
        // current row so that we will
        // be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for(int j = 1; j <= n; j++)
        {
             
            // We will subtract previously
            // computed value  so as to get
            // the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j];
 
            dp[i][j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i][j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 3, 4 };
    int n = arr.length;
    int k = 2;
 
    System.out.print(sumOfProduct(arr, n, k)); 
}
}
 
// This code is contributed by Stream_Cipher


Python3
# Python3 implementation of the approach
  
# Function to return the sum of products of
# all the possible k size subsets
def sumOfProduct(arr, n, k):
     
    # Initialising all the values to 0
    dp = [ [ 0 for x in range(n + 1)] for y in range(n + 1)]
     
    # To store the answer for
    # current value of k
    cur_sum = 0
     
    # For k = 1, the answer will simply
    # be the sum of all the elements
    for i in range(1, n + 1):
        dp[1][i] = arr[i - 1]
        cur_sum += arr[i - 1]
  
    # Filling the table in bottom up manner
    for i in range(2 , k + 1):
  
        # To store the elements of the current
        # row so that we will be able to use this sum
        # for subsequent values of k
        temp_sum = 0
  
        for j in range( 1,  n + 1):
  
            # We will subtract previously computed value
            # so as to get the sum of elements from j + 1
            # to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j]
  
            dp[i][j] = arr[j - 1] * cur_sum
            temp_sum += dp[i][j]
        cur_sum = temp_sum
    return cur_sum
  
# Driver code
if __name__ == "__main__":
     
    arr = [ 1, 2, 3, 4 ]
    n = len(arr)
    k = 2
    print(sumOfProduct(arr, n, k))
 
# This code is contributed by chitranayal


C#
// C# implementation of the approach
using System.Collections.Generic;
using System;
 
class GFG{
 
// Function to return the sum of products of
// all the possible k size subsets
static int sumOfProduct(int []arr, int n, int k)
{
    int [,]dp = new int[n + 1, n + 1];
     
    // Initialising all the values to 0
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= n; j++)
            dp[i, j] = 0;
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for(int i = 1; i <= n; i++)
    {
        dp[1, i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom up manner
    for(int i = 2; i <= k; i++)
    {
         
        // To store the elements of the
        // current row so that we will
        // be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for(int j = 1; j <= n; j++)
        {
             
            // We will subtract previously
            // computed value so as to get
            // the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1, j];
 
            dp[i, j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i, j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
public static void Main()
{
    int []arr = { 1, 2, 3, 4 };
    int n = arr.Length;
    int k = 2;
 
    Console.WriteLine(sumOfProduct(arr, n, k)); 
}
}
 
// This code is contributed by Stream_Cipher


输出 :

35

时间复杂度: 2 n
辅助空间: 2 n (n是数组大小)

高效的方法:以数组a [] = {1,2,3}K = 3为例。然后,

在该示例中,如果需要在K = 2的答案中获得1的贡献,则在先前计算的K = 1的值中,需要元素1的索引之后的所有元素的总和。可以看出,元素23的总和是必需的。因此,对于任何K ,都需要获得针对K – 1的答案。

因此,可以使用自底向上的动态编程方法来解决此问题。创建一个表dp [] []并以自下而上的方式填充它,其中dp [i] [j]将存储元素arr [j – 1]K = i的贡献。因此,递归关系将是

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the sum of products of
// all the possible k size subsets
int sumOfProduct(int arr[], int n, int k)
{
    // Initialising all the values to 0
    int dp[n + 1][n + 1] = { 0 };
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for (int i = 1; i <= n; i++) {
        dp[1][i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom up manner
    for (int i = 2; i <= k; i++) {
 
        // To store the elements of the current
        // row so that we will be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for (int j = 1; j <= n; j++) {
 
            // We will subtract previously computed value
            // so as to get the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j];
 
            dp[i][j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i][j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4 };
    int n = sizeof(arr) / sizeof(int);
    int k = 2;
 
    cout << sumOfProduct(arr, n, k);
 
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
 
class GFG{
 
// Function to return the sum of products of
// all the possible k size subsets
static int sumOfProduct(int arr[], int n,
                        int k)
{
    int dp[][] = new int[n + 1][n + 1];
     
    // Initialising all the values to 0
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= n; j++)
            dp[i][j] = 0;
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for(int i = 1; i <= n; i++)
    {
        dp[1][i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom
    // up manner
    for(int i = 2; i <= k; i++)
    {
         
        // To store the elements of the
        // current row so that we will
        // be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for(int j = 1; j <= n; j++)
        {
             
            // We will subtract previously
            // computed value  so as to get
            // the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j];
 
            dp[i][j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i][j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 3, 4 };
    int n = arr.length;
    int k = 2;
 
    System.out.print(sumOfProduct(arr, n, k)); 
}
}
 
// This code is contributed by Stream_Cipher

Python3

# Python3 implementation of the approach
  
# Function to return the sum of products of
# all the possible k size subsets
def sumOfProduct(arr, n, k):
     
    # Initialising all the values to 0
    dp = [ [ 0 for x in range(n + 1)] for y in range(n + 1)]
     
    # To store the answer for
    # current value of k
    cur_sum = 0
     
    # For k = 1, the answer will simply
    # be the sum of all the elements
    for i in range(1, n + 1):
        dp[1][i] = arr[i - 1]
        cur_sum += arr[i - 1]
  
    # Filling the table in bottom up manner
    for i in range(2 , k + 1):
  
        # To store the elements of the current
        # row so that we will be able to use this sum
        # for subsequent values of k
        temp_sum = 0
  
        for j in range( 1,  n + 1):
  
            # We will subtract previously computed value
            # so as to get the sum of elements from j + 1
            # to n in the (i - 1)th row
            cur_sum -= dp[i - 1][j]
  
            dp[i][j] = arr[j - 1] * cur_sum
            temp_sum += dp[i][j]
        cur_sum = temp_sum
    return cur_sum
  
# Driver code
if __name__ == "__main__":
     
    arr = [ 1, 2, 3, 4 ]
    n = len(arr)
    k = 2
    print(sumOfProduct(arr, n, k))
 
# This code is contributed by chitranayal

C#

// C# implementation of the approach
using System.Collections.Generic;
using System;
 
class GFG{
 
// Function to return the sum of products of
// all the possible k size subsets
static int sumOfProduct(int []arr, int n, int k)
{
    int [,]dp = new int[n + 1, n + 1];
     
    // Initialising all the values to 0
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= n; j++)
            dp[i, j] = 0;
 
    // To store the answer for
    // current value of k
    int cur_sum = 0;
 
    // For k = 1, the answer will simply
    // be the sum of all the elements
    for(int i = 1; i <= n; i++)
    {
        dp[1, i] = arr[i - 1];
        cur_sum += arr[i - 1];
    }
 
    // Filling the table in bottom up manner
    for(int i = 2; i <= k; i++)
    {
         
        // To store the elements of the
        // current row so that we will
        // be able to use this sum
        // for subsequent values of k
        int temp_sum = 0;
 
        for(int j = 1; j <= n; j++)
        {
             
            // We will subtract previously
            // computed value so as to get
            // the sum of elements from j + 1
            // to n in the (i - 1)th row
            cur_sum -= dp[i - 1, j];
 
            dp[i, j] = arr[j - 1] * cur_sum;
            temp_sum += dp[i, j];
        }
        cur_sum = temp_sum;
    }
    return cur_sum;
}
 
// Driver code
public static void Main()
{
    int []arr = { 1, 2, 3, 4 };
    int n = arr.Length;
    int k = 2;
 
    Console.WriteLine(sumOfProduct(arr, n, k)); 
}
}
 
// This code is contributed by Stream_Cipher

输出:

35

时间复杂度: O(N 2 )