给定长度为N的数组arr [] ,任务是找到该数组所有子集的子集的总和。
例子:
Input: arr[] = {1, 1}
Output: 6
All possible subsets:
a) {} : 0
All the possible subsets of this subset
will be {}, Sum = 0
b) {1} : 1
All the possible subsets of this subset
will be {} and {1}, Sum = 0 + 1 = 1
c) {1} : 1
All the possible subsets of this subset
will be {} and {1}, Sum = 0 + 1 = 1
d) {1, 1} : 4
All the possible subsets of this subset
will be {}, {1}, {1} and {1, 1}, Sum = 0 + 1 + 1 + 2 = 4
Thus, ans = 0 + 1 + 1 + 4 = 6
Input: arr[] = {1, 4, 2, 12}
Output: 513
方法:在本文中,将讨论具有O(N)时间复杂度的方法来解决给定的问题。
关键是观察元素在所有子集中重复的次数。
让我们放大视图。众所周知,每个元素在子集总数中将出现2 (N – 1)次。现在,让我们进一步放大视图,看看计数如何随子集大小而变化。
每个包含N的索引都有N – 1个C K –个大小为K的子集。
元素对大小为K的子集的贡献将等于其值的2 (K – 1)倍。因此,元素对长度为K的所有子集的总贡献将等于N – 1 C K – 1 * 2 (K – 1)
所有子集之间的总贡献将等于:
N – 1CN – 1 * 2(N – 1) + N – 1CN – 2 * 2(N – 2 + N – 1CN – 3 * 2(N – 3) + … + N – 1C0 * 20.
现在,最终答案中每个元素的贡献是已知的。因此,将其乘以数组所有元素的总和即可得出所需的答案。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define maxN 10
// To store factorial values
int fact[maxN];
// Function to return ncr
int ncr(int n, int r)
{
return (fact[n] / fact[r]) / fact[n - r];
}
// Function to return the required sum
int findSum(int* arr, int n)
{
// Intialising factorial
fact[0] = 1;
for (int i = 1; i < n; i++)
fact[i] = i * fact[i - 1];
// Multiplier
int mul = 0;
// Finding the value of multipler
// according to the formula
for (int i = 0; i <= n - 1; i++)
mul += (int)pow(2, i) * ncr(n - 1, i);
// To store the final answer
int ans = 0;
// Calculate the final answer
for (int i = 0; i < n; i++)
ans += mul * arr[i];
return ans;
}
// Driver code
int main()
{
int arr[] = { 1, 1 };
int n = sizeof(arr) / sizeof(int);
cout << findSum(arr, n);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static int maxN = 10;
// To store factorial values
static int []fact = new int[maxN];
// Function to return ncr
static int ncr(int n, int r)
{
return (fact[n] / fact[r]) / fact[n - r];
}
// Function to return the required sum
static int findSum(int[] arr, int n)
{
// Intialising factorial
fact[0] = 1;
for (int i = 1; i < n; i++)
fact[i] = i * fact[i - 1];
// Multiplier
int mul = 0;
// Finding the value of multipler
// according to the formula
for (int i = 0; i <= n - 1; i++)
mul += (int)Math.pow(2, i) * ncr(n - 1, i);
// To store the final answer
int ans = 0;
// Calculate the final answer
for (int i = 0; i < n; i++)
ans += mul * arr[i];
return ans;
}
// Driver code
public static void main(String []args)
{
int arr[] = { 1, 1 };
int n = arr.length;
System.out.println(findSum(arr, n));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation of the approach
maxN = 10
# To store factorial values
fact = [0]*maxN;
# Function to return ncr
def ncr(n, r) :
return (fact[n] // fact[r]) // fact[n - r];
# Function to return the required sum
def findSum(arr, n) :
# Intialising factorial
fact[0] = 1;
for i in range(1, n) :
fact[i] = i * fact[i - 1];
# Multiplier
mul = 0;
# Finding the value of multipler
# according to the formula
for i in range(n) :
mul += (2 ** i) * ncr(n - 1, i);
# To store the final answer
ans = 0;
# Calculate the final answer
for i in range(n) :
ans += mul * arr[i];
return ans;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 1 ];
n = len(arr);
print(findSum(arr, n));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
static int maxN = 10;
// To store factorial values
static int []fact = new int[maxN];
// Function to return ncr
static int ncr(int n, int r)
{
return (fact[n] / fact[r]) / fact[n - r];
}
// Function to return the required sum
static int findSum(int[] arr, int n)
{
// Intialising factorial
fact[0] = 1;
for (int i = 1; i < n; i++)
fact[i] = i * fact[i - 1];
// Multiplier
int mul = 0;
// Finding the value of multipler
// according to the formula
for (int i = 0; i <= n - 1; i++)
mul += (int)Math.Pow(2, i) * ncr(n - 1, i);
// To store the final answer
int ans = 0;
// Calculate the final answer
for (int i = 0; i < n; i++)
ans += mul * arr[i];
return ans;
}
// Driver code
public static void Main(String []args)
{
int []arr = { 1, 1 };
int n = arr.Length;
Console.WriteLine(findSum(arr, n));
}
}
// This code is contributed by 29AjayKumar
Javascript
6