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

📅  最后修改于: 2021-09-17 07:15:52             🧑  作者: Mango

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

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

例子:

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

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

高效的方法:这个问题可以使用动态规划和组合学方法来解决。以下是步骤:

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

下面是上述方法的实现。

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


Javascript


输出
3

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