📜  一次获取的所有组合的乘积之和(1到n)

📅  最后修改于: 2021-04-29 17:33:12             🧑  作者: Mango

给定N,我们必须找出一次取1到N的所有组合的乘积之和。简而言之,我们必须找到一次取所有组合的乘积之和,然后一次取2,然后一次取3,直到一次取N。
如果您仔细考虑问题,则N的较大值可能会导致产生许多组合。
例子:

Input :  N = 3
Output : f(1) = 6
         f(2) = 11
         f(3) = 6

Explanation: f(x) is sum of products of all 
             combination taken x at a time
             1 + 2 + 3 = 6
             f(2) = (1*2) + (1*3) + (2*3) = 11
             f(3) = (1*2*3) 

Input :  N = 4
Output : f(1) = 10
         f(2) = 35
         f(3) = 50
         f(4) = 24

Explanation: f(1) = 1 + 2 + 3 + 4 = 10
             f(2) = (1*2) + (1*3) + (1*4) + 
                    (2*3) + (2*4) + (3*4) 
                  = 35
             f(3) = (1*2*3) + (1*2*4) +(1*3*4) + 
                    (2*3*4) 
                 = 50
             f(4) = (1*2*3*4) = 24        

蛮力方法是产生所有组合,然后找到它们的乘积和总和。
递归可以解决一次生成x组合的问题。
示例: N = 4,一次取3

C++
// Program to find SOP of all combination taken
// (1 to N) at a time using brute force
#include 
using namespace std;
 
// to store sum of every combination
int sum = 0;
 
void Combination(int a[], int combi[], int n,
                int r, int depth, int index) {
 
  // if we have reached sufficient depth
  if (index == r) {
     
    // find the product of combination
    int product = 1;
    for (int i = 0; i < r; i++)
      product = product * combi[i];
 
    // add the product into sum
    sum += product;
    return;
  }
 
  // recursion to produce different combination
  for (int i = depth; i < n; i++) {
    combi[index] = a[i];
    Combination(a, combi, n, r, i + 1, index + 1);
  }
}
 
// function to print sum of products of
// all combination taken 1-N at a time
void allCombination(int a[], int n) {
  for (int i = 1; i <= n; i++) {
 
    // creating temporary array for storing
    // combination
    int *combi = new int[i];
 
    // call combination with r = i
    // for combination taken i at a time
    Combination(a, combi, n, i, 0, 0);
 
    // displaying sum
    cout << "f(" << i << ") --> " << sum << "\n";
    sum = 0;
 
    // free from heap area
    free(combi);
  }
}
 
// Driver's code
int main() {
  int n = 5;
  int *a = new int[n];
 
  // storing numbers from 1-N in array
  for (int i = 0; i < n; i++)
    a[i] = i + 1;
 
  // calling allCombination
  allCombination(a, n);
 
  return 0;
}


Java
// Program to find SOP of
// all combination taken
// (1 to N) at a time using
// brute force
import java.io.*;
 
class GFG
{
    // to store sum of
    // every combination
    static int sum = 0;
     
    static void Combination(int []a, int []combi,
                            int n, int r,
                            int depth, int index)
    {
     
    // if we have reached
    // sufficient depth
    if (index == r)
    {
         
        // find the product
        // of combination
        int product = 1;
        for (int i = 0; i < r; i++)
        product = product * combi[i];
     
        // add the product into sum
        sum += product;
        return;
    }
     
    // recursion to produce
    // different combination
    for (int i = depth; i < n; i++)
    {
        combi[index] = a[i];
        Combination(a, combi, n, r,
                    i + 1, index + 1);
    }
    }
     
    // function to print sum of
    // products of all combination
    // taken 1-N at a time
    static void allCombination(int []a,
                               int n)
    {
        for (int i = 1; i <= n; i++)
        {
         
            // creating temporary array
            // for storing combination
            int []combi = new int[i];
         
            // call combination with
            // r = i for combination
            // taken i at a time
            Combination(a, combi, n,
                        i, 0, 0);
         
            // displaying sum
            System.out.print("f(" + i + ") --> " +
                                      sum + "\n");
            sum = 0;
        }
    }
     
    // Driver code
    public static void main(String args[])
    {
        int n = 5;
        int []a = new int[n];
         
        // storing numbers
        // from 1-N in array
        for (int i = 0; i < n; i++)
            a[i] = i + 1;
         
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by
// Manish Shaw(manishshaw1)


Python3
# Python3 Program to find SOP of all combination
# taken (1 to N) at a time using brute force
 
# to store sum of every combination
def Combination(a, combi, n, r, depth, index):
    global Sum
     
    # if we have reached sufficient depth
    if index == r:
     
        # find the product of combination
        product = 1
        for i in range(r):
            product = product * combi[i]
     
        # add the product into sum
        Sum += product
        return
 
    # recursion to produce different
    # combination
    for i in range(depth, n):
        combi[index] = a[i]
        Combination(a, combi, n, r,
                    i + 1, index + 1)
 
# function to print sum of products of
# all combination taken 1-N at a time
def allCombination(a, n):
    global Sum
    for i in range(1, n + 1):
         
        # creating temporary array for
        # storing combination
        combi = [0] * i
     
        # call combination with r = i
        # for combination taken i at a time
        Combination(a, combi, n, i, 0, 0)
     
        # displaying sum
        print("f(", i, ") --> ", Sum)
        Sum = 0
 
# Driver Code
Sum = 0
n = 5
a = [0] * n
 
# storing numbers from 1-N in array
for i in range(n):
    a[i] = i + 1
 
# calling allCombination
allCombination(a, n)
 
# This code is contributed by PranchalK


C#
// Program to find SOP of
// all combination taken
// (1 to N) at a time using
// brute force
using System;
 
class GFG
{
    // to store sum of
    // every combination
    static int sum = 0;
     
    static void Combination(int []a, int []combi,
                            int n, int r,
                            int depth, int index)
    {
     
    // if we have reached
    // sufficient depth
    if (index == r)
    {
         
        // find the product
        // of combination
        int product = 1;
        for (int i = 0; i < r; i++)
        product = product * combi[i];
     
        // add the product into sum
        sum += product;
        return;
    }
     
    // recursion to produce
    // different combination
    for (int i = depth; i < n; i++)
    {
        combi[index] = a[i];
        Combination(a, combi, n, r,
                    i + 1, index + 1);
    }
    }
     
    // function to print sum of
    // products of all combination
    // taken 1-N at a time
    static void allCombination(int []a,
                               int n)
    {
    for (int i = 1; i <= n; i++)
    {
     
        // creating temporary array
        // for storing combination
        int []combi = new int[i];
     
        // call combination with
        // r = i for combination
        // taken i at a time
        Combination(a, combi, n,
                    i, 0, 0);
     
        // displaying sum
        Console.Write("f(" + i + ") --> " +
                               sum + "\n");
        sum = 0;
    }
    }
     
    // Driver code
    static void Main()
    {
        int n = 5;
        int []a = new int[n];
         
        // storing numbers
        // from 1-N in array
        for (int i = 0; i < n; i++)
            a[i] = i + 1;
         
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by
// Manish Shaw(manishshaw1)


Javascript


C++
// CPP Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
#include 
using namespace std;
 
// find the postfix sum array
void postfix(int a[], int n) {
  for (int i = n - 1; i > 0; i--)
    a[i - 1] = a[i - 1] + a[i];
}
 
// modify the array such that we don't have to
// compute the products which are obtained before
void modify(int a[], int n) {
  for (int i = 1; i < n; i++)
    a[i - 1] = i * a[i];
}
 
// finding sum of all combination taken 1 to N at a time
void allCombination(int a[], int n) {
 
  int sum = 0;
 
  // sum taken 1 at time is simply sum of 1 - N
  for (int i = 1; i <= n; i++)
    sum += i;
  cout << "f(1) --> " << sum << "\n";
 
  // for sum of products for all combination
  for (int i = 1; i < n; i++) {
 
    // finding postfix array
    postfix(a, n - i + 1);
     
    // sum of products taken i+1 at a time
    sum = 0;
    for (int j = 1; j <= n - i; j++) {
      sum += (j * a[j]);
    }
    cout << "f(" << i + 1 << ") --> " << sum << "\n";
 
    // modify the array for overlapping problem
    modify(a, n);
  }
}
 
// Driver's Code
int main() {
  int n = 5;
  int *a = new int[n];
 
  // storing numbers from 1 to N
  for (int i = 0; i < n; i++)
    a[i] = i + 1;
 
  // calling allCombination
  allCombination(a, n);
 
  return 0;
}


Java
// Java Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
import java.util.*;
 
class GFG
{
 
    // find the postfix sum array
    static void postfix(int a[], int n)
    {
        for (int i = n - 1; i > 0; i--)
        {
            a[i - 1] = a[i - 1] + a[i];
        }
    }
 
    // modify the array such that we don't
    // have to compute the products which
    // are obtained before
    static void modify(int a[], int n)
    {
        for (int i = 1; i < n; i++)
        {
            a[i - 1] = i * a[i];
        }
    }
 
    // finding sum of all combination
    // taken 1 to N at a time
    static void allCombination(int a[], int n)
    {
        int sum = 0;
 
        // sum taken 1 at time is simply sum of 1 - N
        for (int i = 1; i <= n; i++)
        {
            sum += i;
        }
        System.out.println("f(1) --> " + sum);
 
        // for sum of products for all combination
        for (int i = 1; i < n; i++)
        {
 
            // finding postfix array
            postfix(a, n - i + 1);
 
            // sum of products taken i+1 at a time
            sum = 0;
            for (int j = 1; j <= n - i; j++)
            {
                sum += (j * a[j]);
            }
            System.out.println("f(" + (i + 1) +
                               ") --> " + sum);
 
            // modify the array for overlapping problem
            modify(a, n);
        }
    }
 
    // Driver's Code
    public static void main(String[] args)
    {
        int n = 5;
        int[] a = new int[n];
 
        // storing numbers from 1 to N
        for (int i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
 
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 Program to find
# sum of all combination takne
# (1 to N) at a time using
# dynamic programming
 
# Find the postfix sum array
def postfix(a, n):
   
    for i in range (n - 1, 1, -1):
        a[i - 1] = a[i - 1] + a[i]
 
# Modify the array such
# that we don't have to
# compute the products
# which are obtained before
def modify(a, n):
   
    for i in range (1, n):
        a[i - 1] = i * a[i];
 
# Finding sum of all combination
# taken 1 to N at a time
def allCombination(a, n):
 
    sum = 0
 
    # sum taken 1 at time is
    # simply sum of 1 - N
    for i in range (1, n + 1):
       
        sum += i
    print ("f(1) --> ", sum )
 
    # for sum of products for
    # all combination
    for i in range (1, n):
 
        # finding postfix array
        postfix(a, n - i + 1)
     
        # sum of products taken
        # i+1 at a time
        sum = 0
         
        for j in range(1, n - i + 1):
            sum += (j * a[j])
     
        print ("f(", i + 1, ") --> ", sum)
 
        # modify the array for
        # overlapping problem
        modify(a, n)
 
# Driver's Code
if __name__ == "__main__":
 
    n = 5
    a = [0] * n
 
    # storing numbers
    # from 1 to N
    for i in range(n):
        a[i] = i + 1
 
    # calling allCombination
    allCombination(a, n)
 
# This code is contributed by Chitranayal


C#
// C# Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
using System;
     
class GFG
{
 
    // find the postfix sum array
    static void postfix(int []a, int n)
    {
        for (int i = n - 1; i > 0; i--)
        {
            a[i - 1] = a[i - 1] + a[i];
        }
    }
 
    // modify the array such that we don't
    // have to compute the products which
    // are obtained before
    static void modify(int []a, int n)
    {
        for (int i = 1; i < n; i++)
        {
            a[i - 1] = i * a[i];
        }
    }
 
    // finding sum of all combination
    // taken 1 to N at a time
    static void allCombination(int []a, int n)
    {
        int sum = 0;
 
        // sum taken 1 at time is simply sum of 1 - N
        for (int i = 1; i <= n; i++)
        {
            sum += i;
        }
        Console.WriteLine("f(1) --> " + sum);
 
        // for sum of products for all combination
        for (int i = 1; i < n; i++)
        {
 
            // finding postfix array
            postfix(a, n - i + 1);
 
            // sum of products taken i+1 at a time
            sum = 0;
            for (int j = 1; j <= n - i; j++)
            {
                sum += (j * a[j]);
            }
            Console.WriteLine("f(" + (i + 1) +
                            ") --> " + sum);
 
            // modify the array for overlapping problem
            modify(a, n);
        }
    }
 
    // Driver's Code
    public static void Main(String[] args)
    {
        int n = 5;
        int[] a = new int[n];
 
        // storing numbers from 1 to N
        for (int i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
 
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by Rajput-Ji


输出:

f(1) --> 15
f(2) --> 85
f(3) --> 225
f(4) --> 274
f(5) --> 120

当N的值较大时,以上代码的时间复杂度是指数级的。
一种有效的方法是使用动态编程的概念。我们不必每次都找到产品的总和。我们可以利用以前的结果。
让我们举个例子:N = 4

C++

// CPP Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
#include 
using namespace std;
 
// find the postfix sum array
void postfix(int a[], int n) {
  for (int i = n - 1; i > 0; i--)
    a[i - 1] = a[i - 1] + a[i];
}
 
// modify the array such that we don't have to
// compute the products which are obtained before
void modify(int a[], int n) {
  for (int i = 1; i < n; i++)
    a[i - 1] = i * a[i];
}
 
// finding sum of all combination taken 1 to N at a time
void allCombination(int a[], int n) {
 
  int sum = 0;
 
  // sum taken 1 at time is simply sum of 1 - N
  for (int i = 1; i <= n; i++)
    sum += i;
  cout << "f(1) --> " << sum << "\n";
 
  // for sum of products for all combination
  for (int i = 1; i < n; i++) {
 
    // finding postfix array
    postfix(a, n - i + 1);
     
    // sum of products taken i+1 at a time
    sum = 0;
    for (int j = 1; j <= n - i; j++) {
      sum += (j * a[j]);
    }
    cout << "f(" << i + 1 << ") --> " << sum << "\n";
 
    // modify the array for overlapping problem
    modify(a, n);
  }
}
 
// Driver's Code
int main() {
  int n = 5;
  int *a = new int[n];
 
  // storing numbers from 1 to N
  for (int i = 0; i < n; i++)
    a[i] = i + 1;
 
  // calling allCombination
  allCombination(a, n);
 
  return 0;
}

Java

// Java Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
import java.util.*;
 
class GFG
{
 
    // find the postfix sum array
    static void postfix(int a[], int n)
    {
        for (int i = n - 1; i > 0; i--)
        {
            a[i - 1] = a[i - 1] + a[i];
        }
    }
 
    // modify the array such that we don't
    // have to compute the products which
    // are obtained before
    static void modify(int a[], int n)
    {
        for (int i = 1; i < n; i++)
        {
            a[i - 1] = i * a[i];
        }
    }
 
    // finding sum of all combination
    // taken 1 to N at a time
    static void allCombination(int a[], int n)
    {
        int sum = 0;
 
        // sum taken 1 at time is simply sum of 1 - N
        for (int i = 1; i <= n; i++)
        {
            sum += i;
        }
        System.out.println("f(1) --> " + sum);
 
        // for sum of products for all combination
        for (int i = 1; i < n; i++)
        {
 
            // finding postfix array
            postfix(a, n - i + 1);
 
            // sum of products taken i+1 at a time
            sum = 0;
            for (int j = 1; j <= n - i; j++)
            {
                sum += (j * a[j]);
            }
            System.out.println("f(" + (i + 1) +
                               ") --> " + sum);
 
            // modify the array for overlapping problem
            modify(a, n);
        }
    }
 
    // Driver's Code
    public static void main(String[] args)
    {
        int n = 5;
        int[] a = new int[n];
 
        // storing numbers from 1 to N
        for (int i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
 
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 Program to find
# sum of all combination takne
# (1 to N) at a time using
# dynamic programming
 
# Find the postfix sum array
def postfix(a, n):
   
    for i in range (n - 1, 1, -1):
        a[i - 1] = a[i - 1] + a[i]
 
# Modify the array such
# that we don't have to
# compute the products
# which are obtained before
def modify(a, n):
   
    for i in range (1, n):
        a[i - 1] = i * a[i];
 
# Finding sum of all combination
# taken 1 to N at a time
def allCombination(a, n):
 
    sum = 0
 
    # sum taken 1 at time is
    # simply sum of 1 - N
    for i in range (1, n + 1):
       
        sum += i
    print ("f(1) --> ", sum )
 
    # for sum of products for
    # all combination
    for i in range (1, n):
 
        # finding postfix array
        postfix(a, n - i + 1)
     
        # sum of products taken
        # i+1 at a time
        sum = 0
         
        for j in range(1, n - i + 1):
            sum += (j * a[j])
     
        print ("f(", i + 1, ") --> ", sum)
 
        # modify the array for
        # overlapping problem
        modify(a, n)
 
# Driver's Code
if __name__ == "__main__":
 
    n = 5
    a = [0] * n
 
    # storing numbers
    # from 1 to N
    for i in range(n):
        a[i] = i + 1
 
    # calling allCombination
    allCombination(a, n)
 
# This code is contributed by Chitranayal

C#

// C# Program to find sum of all combination takne
// (1 to N) at a time using dynamic programming
using System;
     
class GFG
{
 
    // find the postfix sum array
    static void postfix(int []a, int n)
    {
        for (int i = n - 1; i > 0; i--)
        {
            a[i - 1] = a[i - 1] + a[i];
        }
    }
 
    // modify the array such that we don't
    // have to compute the products which
    // are obtained before
    static void modify(int []a, int n)
    {
        for (int i = 1; i < n; i++)
        {
            a[i - 1] = i * a[i];
        }
    }
 
    // finding sum of all combination
    // taken 1 to N at a time
    static void allCombination(int []a, int n)
    {
        int sum = 0;
 
        // sum taken 1 at time is simply sum of 1 - N
        for (int i = 1; i <= n; i++)
        {
            sum += i;
        }
        Console.WriteLine("f(1) --> " + sum);
 
        // for sum of products for all combination
        for (int i = 1; i < n; i++)
        {
 
            // finding postfix array
            postfix(a, n - i + 1);
 
            // sum of products taken i+1 at a time
            sum = 0;
            for (int j = 1; j <= n - i; j++)
            {
                sum += (j * a[j]);
            }
            Console.WriteLine("f(" + (i + 1) +
                            ") --> " + sum);
 
            // modify the array for overlapping problem
            modify(a, n);
        }
    }
 
    // Driver's Code
    public static void Main(String[] args)
    {
        int n = 5;
        int[] a = new int[n];
 
        // storing numbers from 1 to N
        for (int i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
 
        // calling allCombination
        allCombination(a, n);
    }
}
 
// This code is contributed by Rajput-Ji

输出:

f(1) --> 15
f(2) --> 85
f(3) --> 225
f(4) --> 274
f(5) --> 120

上述方法的时间复杂度为O(n ^ 2),远优于蛮力法。
对于较大的N值,您还可以找到这两种方法的执行时间,并且自己可以看到差异。