给定一个大小为N的数组arr[] ,任务是找到可能(大于 1)的正整数序列的总数,其乘积正好是X 。 X的值计算为项的乘积,其中第i 项是通过将第i个素数提高到arr[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[]的总和。
- 然后使用动态规划来填充可能序列中的槽位,从索引 i 开始,从 1 到序列的长度。
- 对于每个具有P[j]值的第 j 个素数,将所有P[j] 个素数划分到每个 i 个槽中。
- 使用组合方法将P[j]元素划分为 i 个槽。将值存储在数组way[] 中,从而使 way[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 个素数中的每一个,将乘法所描述的值相乘。
- 然而, 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)