给定一个由N 个非负整数组成的数组arr[]和一个整数1 ≤ K ≤ N 。任务是找到大小为K的arr[]的所有可能子集的乘积之和。
例子:
Input: arr[] = {1, 2, 3, 4}, K = 2
Output: 35
(1 * 2) + (1 * 3) + (1 * 4) + (2 * 3) + (2 * 4)
+ (3 * 4) = 2 + 3 + 4 + 6 + 8 + 12 = 35
Input: arr[] = {1, 2, 3, 4}, K = 3
Output: 50
朴素的方法:生成大小为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
Javascript
输出 :
35
时间复杂度: 2 n
辅助空间: 2 n (n 是数组大小)
有效的方法:以数组a[] = {1, 2, 3}和K = 3为例。然后,
k = 1, answer = 1 + 2 + 3 = 6
k = 2, answer = 1 * (2 + 3) + 2 * 3 + 0 = 11
k = 3, answer = 1 * (2 * 3 + 0) + 0 + 0 = 6
在该示例中,如果需要在K = 2的答案中获得1的贡献,则在先前计算的K = 1值中需要元素1的索引之后的所有元素的总和。可以看出需要元素2和3的总和。因此,对于任何K ,都需要为K – 1获得的答案。
因此,可以使用自底向上的动态规划方法来解决这个问题。创建一个表dp[][]并以自下而上的方式填充它,其中dp[i][j]将存储元素arr[j – 1]对K = i答案的贡献。因此,递推关系将是,
dp[i][j] = arr[j-1] *
dp[i-1][k]
answer[k] =
dp[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
蟒蛇3
# 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
Javascript
输出:
35
时间复杂度: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。