📜  计算具有乘积X的正整数序列

📅  最后修改于: 2021-04-22 08:58:12             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是查找可能正整数(大于1)的乘积正好为X的序列总数。 X的值被计算为项的乘积,其中通过将i素数提高到arr [i]的幂来生成i项。

注意:由于此类序列的总数可能非常大,因此请以10 9 + 7为模数打印答案。

例子:

天真的方法:这个想法是首先计算X的值,然后使用递归生成乘积为X的所有可能序列。

时间复杂度: O(2 N )
辅助空间: O(1)

高效方法:可以使用动态规划和组合方法解决此问题。步骤如下:

  • 首先,找到在所有可能的序列中可以出现的最大正元素数,这将是给定数组arr []的总和。
  • 然后使用动态编程在可能的序列中填充从1到序列长度的索引i的时隙。
    • 对于具有值P [j]的每个第j个素数,将所有P [j]素数划分为i个时隙中的每一个。
    • 使用组合方法P [j]个元素划分为i个时隙。将值存储在数组Ways []中,以便Ways [i]如下更新:
  • 对于j个素数中的每个素数,将值相乘,如乘法所示。
  • 但是, Ways []也将包含一个或多个1个时隙为空的序列,因此,对于填充的时隙数小于i的所有时隙,均应减去其确切贡献。
  • 对于每一个从j = 1至i – 1,i选择Ĵ槽和减去它的贡献。
  • 最后,将数组Ways []的所有值相加以获得总结果。

下面是上述方法的实现。

C++
// C++ program for the above approach
#include 
using namespace std;
 
int bin[3000][3000];
 
// Function to print the total number
// of possible sequences with
// product X
void countWays(const vector& arr)
{
    int mod = 1e9 + 7;
    bin[0][0] = 1;
 
    // Precomputation of
    // binomial coefficients
    for (int i = 1; i < 3000; i++) {
        bin[i][0] = 1;
        for (int j = 1; j <= i; j++) {
            bin[i][j] = (bin[i - 1][j]
                         + bin[i - 1][j - 1])
                        % mod;
        }
    }
 
    // Max length of a subsequence
    int n = 0;
    for (auto x : arr)
        n += x;
 
    // Ways dp array
    vector ways(n + 1);
 
    for (int i = 1; i <= n; i++) {
        ways[i] = 1;
 
        // Fill i slots using all
        // the primes
        for (int j = 0;
             j < (int)arr.size(); j++) {
            ways[i] = (ways[i]
                       * bin[arr[j] + i - 1]
                            [i - 1])
                      % mod;
        }
 
        // Subtract ways for all
        // slots that exactly
        // fill less than i slots
        for (int j = 1; j < i; j++) {
            ways[i] = ((ways[i]
                        - bin[i][j] * ways[j])
                           % mod
                       + mod)
                      % mod;
        }
    }
 
    // Total possible sequences
    int ans = 0;
    for (auto x : ways)
        ans = (ans + x) % mod;
 
    // Print the resultant count
    cout << ans << endl;
}
 
// Driver Code
int main()
{
    vector arr = { 1, 1 };
 
    // Function call
    countWays(arr);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
static int [][]bin = new int[3000][3000];
 
// Function to print the total number
// of possible sequences with
// product X
static void countWays(int[] arr)
{
    int mod = (int)1e9 + 7;
    bin[0][0] = 1;
 
    // Precomputation of
    // binomial coefficients
    for(int i = 1; i < 3000; i++)
    {
        bin[i][0] = 1;
        for(int j = 1; j <= i; j++)
        {
            bin[i][j] = (bin[i - 1][j] +
                         bin[i - 1][j - 1]) % mod;
        }
    }
 
    // Max length of a subsequence
    int n = 0;
    for(int x : arr)
        n += x;
 
    // Ways dp array
    int[] ways = new int[n + 1];
 
    for(int i = 1; i <= n; i++)
    {
        ways[i] = 1;
 
        // Fill i slots using all
        // the primes
        for(int j = 0; j < arr.length; j++)
        {
            ways[i] = (ways[i] *
                    bin[arr[j] + i - 1][i - 1]) % mod;
        }
 
        // Subtract ways for all
        // slots that exactly
        // fill less than i slots
        for(int j = 1; j < i; j++)
        {
            ways[i] = ((ways[i] - bin[i][j] *
                        ways[j]) % mod + mod) % mod;
        }
    }
 
    // Total possible sequences
    int ans = 0;
    for(int x : ways)
        ans = (ans + x) % mod;
 
    // Print the resultant count
    System.out.print(ans + "\n");
}
 
// Driver Code
public static void main(String[] args)
{
    int[] arr = { 1, 1 };
 
    // Function call
    countWays(arr);
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program for the above approach
bin = [[0 for i in range(3000)]
          for i in range(3000)]
 
# Function to prthe total number
# of possible sequences with
# product X
def countWays(arr):
     
    mod = 10**9 + 7
    bin[0][0] = 1
 
    # Precomputation of
    # binomial coefficients
    for i in range(1, 3000):
        bin[i][0] = 1
         
        for j in range(1, i + 1):
            bin[i][j] = (bin[i - 1][j] +
                         bin[i - 1][j - 1]) % mod
 
    # Max length of a subsequence
    n = 0
     
    for x in arr:
        n += x
 
    # Ways dp array
    ways = [0] * (n + 1)
 
    for i in range(1, n + 1):
        ways[i] = 1
 
        # Fill i slots using all
        # the primes
        for j in range(len(arr)):
            ways[i] = (ways[i] *
                    bin[arr[j] + i - 1][i - 1]) % mod
 
        # Subtract ways for all
        # slots that exactly
        # fill less than i slots
        for j in range(1, i):
            ways[i] = ((ways[i] - bin[i][j] *
                        ways[j]) % mod + mod) % mod
 
    # Total possible sequences
    ans = 0
     
    for x in ways:
        ans = (ans + x) % mod
 
    # Print the resultant count
    print(ans)
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 1 ]
 
    # Function call
    countWays(arr)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
 
class GFG{
 
static int [,]bin = new int[3000, 3000];
 
// Function to print the total number
// of possible sequences with
// product X
static void countWays(int[] arr)
{
    int mod = (int)1e9 + 7;
    bin[0, 0] = 1;
 
    // Precomputation of
    // binomial coefficients
    for(int i = 1; i < 3000; i++)
    {
        bin[i, 0] = 1;
        for(int j = 1; j <= i; j++)
        {
            bin[i, j] = (bin[i - 1, j] +
                         bin[i - 1, j - 1]) % mod;
        }
    }
 
    // Max length of a subsequence
    int n = 0;
    foreach(int x in arr)
        n += x;
 
    // Ways dp array
    int[] ways = new int[n + 1];
 
    for(int i = 1; i <= n; i++)
    {
        ways[i] = 1;
 
        // Fill i slots using all
        // the primes
        for(int j = 0; j < arr.Length; j++)
        {
            ways[i] = (ways[i] *
                    bin[arr[j] + i - 1, i - 1]) % mod;
        }
 
        // Subtract ways for all
        // slots that exactly
        // fill less than i slots
        for(int j = 1; j < i; j++)
        {
            ways[i] = ((ways[i] - bin[i, j] *
                        ways[j]) % mod + mod) % mod;
        }
    }
 
    // Total possible sequences
    int ans = 0;
    foreach(int x in ways)
        ans = (ans + x) % mod;
 
    // Print the resultant count
    Console.Write(ans + "\n");
}
 
// Driver Code
public static void Main(String[] args)
{
    int[] arr = { 1, 1 };
 
    // Function call
    countWays(arr);
}
}
 
// This code is contributed by Amit Katiyar


输出
3

时间复杂度: O(N 2 )
辅助空间: O(N)