给定大小为N的数组arr [] ,任务是查找可能正整数(大于1)的乘积正好为X的序列总数。 X的值被计算为项的乘积,其中通过将第i个素数提高到arr [i]的幂来生成第i个项。
X = 2 ^ arr[1] * 3 ^ arr[2] * 5 ^ arr[3] * 7 ^ arr[4] * 11 ^ arr[5] * … up to Nth term
注意:由于此类序列的总数可能非常大,因此请以10 9 + 7为模数打印答案。
例子:
Input: arr[] = {1, 1}
Output: 3
Explanation:
Here, X = 2^1 * 3^1 = 6
Possible positive sequences whose product is X: {2, 3}, {3, 2}, {6}
Input: arr[] = {2}
Output: 2
Explanation:
Here, X = 2^2 = 4.
Possible positive sequences whose product is X: {2, 2} and {4}.
天真的方法:这个想法是首先计算X的值,然后使用递归生成乘积为X的所有可能序列。
时间复杂度: O(2 N )
辅助空间: O(1)
高效方法:可以使用动态规划和组合方法解决此问题。步骤如下:
- 首先,找到在所有可能的序列中可以出现的最大正元素数,这将是给定数组arr []的总和。
- 然后使用动态编程在可能的序列中填充从1到序列长度的索引i的时隙。
- 对于具有值P [j]的每个第j个素数,将所有P [j]素数划分为i个时隙中的每一个。
- 使用组合方法将P [j]个元素划分为i个时隙。将值存储在数组Ways []中,以便Ways [i]如下更新:
Number of ways to divide N identical elements into K slots = (N + K – 1)C(K – 1)
This approach is also known as Stars and Bars approach formally in Combinatorics.
- 对于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)