 Open in App
Not now

# Count of valid arrays of size P with elements in range [1, N] having duplicates at least M distance apart

• Difficulty Level : Expert
• Last Updated : 04 Aug, 2022

Go to CDN’s CopyGiven three integers N, M and P, the task is to find the total number of valid arrays that can be created of size P having each element in range [1, N], such that the duplicates appear at least M distance apart.

Example:

Input: N = 2, M = 0, P = 3
Output: 6
Explanation: All valid arrays are: {1, 2, 1}, {1, 1, 2}, {2, 1, 1}, {2, 2, 1}, {2, 1, 2}, {1, 2, 2}.

Input: N = 2, M = 1, P = 4
Output: 2
Explanation: All valid arrays are: {1, 2, 1, 2}, {2, 1, 2, 1}

Approach: The problem can be solved with the help of Dynamic Programming,

• There are two choices possible at each index are : either we append already used element at least M distance apart, or we append a new element and decrement the count of unused characters.
• To handle this, use recursive dynamic programming.
• To speed up the recursive calls, use memoization so that already calculated states are not calculated again.
• Let’s define:  dp[i][j][k] as the number of arrays till i-th position in which j unique elements are present and k be number of elements which are not used.
• At each step there are two options:
1. Choose previously occurred elements, j and k wouldn’t change as number of used and unused elements doesn’t change : dp[i+1][j][k]
2. Choose element that has never been used, for this case, the number of used character will increment by 1 and the number of unused characters will decrement by 1 : dp[i+1][j+1][k-1]

dp[i][j][k] will be the summation of above two steps, represented as :

•

dp[i][j][k] = dp[i+1][j][k] + dp[i+1][j+1][k-1]

• The final answer will be dp[N].

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to calculate the total``// number of arrays``int` `calculate(``int` `position, ``int` `used, ``int` `unused, ``int` `P,``              ``int` `M, vector > >& dp)``{``    ``// If the size of the array is P``    ``if` `(position == P) {``        ``// Check if all elements are``        ``// used atleast once``        ``return` `unused == 0 ? 1 : 0;``    ``}` `    ``// Check if this state is already``    ``// calculated``    ``if` `(dp[position][used][unused] != -1)``        ``return` `dp[position][used][unused];` `    ``// Initialize the result``    ``int` `result = 0;` `    ``// Use a number from the list of``    ``// unused numbers``    ``if` `(unused > 0) {``        ``// There are 'unused' number of``        ``// favourable choices``        ``result += calculate(position + 1, used + 1,``                            ``unused - 1, P, M, dp)``                  ``* unused;``    ``}` `    ``// Use a number from already present number``    ``// atlease M distance back``    ``if` `(used > M) {``        ``// There are 'used - M' number of``        ``// favourable choices``        ``result += calculate(position + 1,``                            ``used, unused, P,``                            ``M, dp)``                  ``* (used - M);``    ``}` `    ``// Store the result``    ``return` `dp[position][used][unused] = result;``}` `// Function to solve the problem``int` `solve(``int` `N, ``int` `P, ``int` `M)``{``    ``// Initialize DP table : dp[i][j][j]``    ``// i : current position/index``    ``// j : number of used elements``    ``// k : number of unused elements``    ``vector > > dp(``        ``101,``        ``vector >(101,``                             ``vector<``int``>(101, -1)));` `    ``return` `calculate(0, 0, N, P, M, dp);``}``// Driver Code``int` `main()``{``    ``int` `N = 2, M = 0, P = 3;``    ``cout << solve(N, P, M);``}`

## Java

 `// Java program for the above approach``import` `java.io.*;``class` `GFG``{` `  ``// Function to calculate the total``  ``// number of arrays``  ``static` `int` `calculate(``int` `position, ``int` `used, ``int` `unused, ``int` `P,``                       ``int` `M, ``int` `dp[][][])``  ``{``    ``// If the size of the array is P``    ``if` `(position == P)``    ``{``      ` `      ``// Check if all elements are``      ``// used atleast once``      ``return` `unused == ``0` `? ``1` `: ``0``;``    ``}` `    ``// Check if this state is already``    ``// calculated``    ``if` `(dp[position][used][unused] != -``1``)``      ``return` `dp[position][used][unused];` `    ``// Initialize the result``    ``int` `result = ``0``;` `    ``// Use a number from the list of``    ``// unused numbers``    ``if` `(unused > ``0``) {``      ``// There are 'unused' number of``      ``// favourable choices``      ``result += calculate(position + ``1``, used + ``1``,``                          ``unused - ``1``, P, M, dp)``        ``* unused;``    ``}` `    ``// Use a number from already present number``    ``// atlease M distance back``    ``if` `(used > M)``    ``{``      ` `      ``// There are 'used - M' number of``      ``// favourable choices``      ``result += calculate(position + ``1``,``                          ``used, unused, P,``                          ``M, dp)``        ``* (used - M);``    ``}` `    ``// Store the result``    ``return` `dp[position][used][unused] = result;``  ``}` `  ``// Function to solve the problem``  ``static` `int` `solve(``int` `N, ``int` `P, ``int` `M)``  ``{``    ``// Initialize DP table : dp[i][j][j]``    ``// i : current position/index``    ``// j : number of used elements``    ``// k : number of unused elements``    ``int``[][][] dp = ``new` `int``[``101``][``101``][``101``];``    ``for``(``int` `i = ``0``; i < ``101``; i++)``    ``{``      ``for``(``int` `j = ``0``; j < ``101``; j++)``        ``for``(``int` `k = ``0``; k < ``101``; k++)``          ``dp[i][j][k] = -``1``;``    ``}``    ``return` `calculate(``0``, ``0``, N, P, M, dp);``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``2``, M = ``0``, P = ``3``;``    ``System.out.println(solve(N, P, M));``  ``}``}` `// This code is contributed by dwivediyash`

## Python3

 `# Python 3 program for the above approach` `# Function to calculate the total``# number of arrays``def` `calculate(position, used, unused, P, M, dp):``  ` `    ``# If the size of the array is P``    ``if` `(position ``=``=` `P):``      ` `        ``# Check if all elements are``        ``# used atleast once``        ``if` `unused ``=``=` `0``:``          ``return` `1``        ``else``:``          ``return` `0` `    ``# Check if this state is already``    ``# calculated``    ``if` `(dp[position][used][unused] !``=` `-``1``):``        ``return` `dp[position][used][unused]` `    ``# Initialize the result``    ``result ``=` `0` `    ``# Use a number from the list of``    ``# unused numbers``    ``if` `(unused > ``0``):``      ` `        ``# There are 'unused' number of``        ``# favourable choices``        ``result ``+``=` `calculate(position ``+` `1``, used ``+` `1``,unused ``-` `1``, P, M, dp)``*` `unused` `    ``# Use a number from already present number``    ``# atlease M distance back``    ``if` `(used > M):``      ` `        ``# There are 'used - M' number of``        ``# favourable choices``        ``result ``+``=` `calculate(position ``+` `1``,used, unused, P,M, dp)``*` `(used ``-` `M)``    ``dp[position][used][unused] ``=` `result` `    ``# Store the result``    ``return` `dp[position][used][unused]` `# Function to solve the problem``def` `solve(N, P, M):``  ` `    ``# Initialize DP table : dp[i][j][j]``    ``# i : current position/index``    ``# j : number of used elements``    ``# k : number of unused elements``    ``dp ``=` `[[[``-``1` `for` `i ``in` `range``(``101``)] ``for` `i ``in` `range``(``101``)] ``for` `j ``in` `range``(``101``)]` `    ``return` `calculate(``0``, ``0``, N, P, M, dp)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``N ``=` `2``    ``M ``=` `0``    ``P ``=` `3``    ``print``(solve(N, P, M))``    ` `    ``# This code is contributed by SURENDRA_GANGWAR.`

## C#

 `// C# program for the above approach``using` `System;` `public` `class` `GFG``{` `  ``// Function to calculate the total``  ``// number of arrays``  ``static` `int` `calculate(``int` `position, ``int` `used, ``int` `unused, ``int` `P,``                       ``int` `M, ``int` `[,,]dp)``  ``{``    ` `    ``// If the size of the array is P``    ``if` `(position == P)``    ``{``      ` `      ``// Check if all elements are``      ``// used atleast once``      ``return` `unused == 0 ? 1 : 0;    ``    ``}` `    ``// Check if this state is already``    ``// calculated``    ``if` `(dp[position,used,unused] != -1)``      ``return` `dp[position,used,unused];` `    ``// Initialize the result``    ``int` `result = 0;` `    ``// Use a number from the list of``    ``// unused numbers``    ``if` `(unused > 0)``    ``{``      ` `      ``// There are 'unused' number of``      ``// favourable choices``      ``result += calculate(position + 1, used + 1,``                          ``unused - 1, P, M, dp)``        ``* unused;``    ``}` `    ``// Use a number from already present number``    ``// atlease M distance back``    ``if` `(used > M)``    ``{``      ` `      ``// There are 'used - M' number of``      ``// favourable choices``      ``result += calculate(position + 1,``                          ``used, unused, P,``                          ``M, dp)``        ``* (used - M);``    ``}` `    ``// Store the result``    ``return` `dp[position,used,unused] = result;``  ``}` `  ``// Function to solve the problem``  ``static` `int` `solve(``int` `N, ``int` `P, ``int` `M)``  ``{``    ` `    ``// Initialize DP table : dp[i,j,j]``    ``// i : current position/index``    ``// j : number of used elements``    ``// k : number of unused elements``    ``int``[,,] dp = ``new` `int``[101,101,101];``    ``for``(``int` `i = 0; i < 101; i++)``    ``{``      ``for``(``int` `j = 0; j < 101; j++)``        ``for``(``int` `k = 0; k < 101; k++)``          ``dp[i, j, k] = -1;``    ``}``    ``return` `calculate(0, 0, N, P, M, dp);``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args)``  ``{``    ``int` `N = 2, M = 0, P = 3;``    ``Console.WriteLine(solve(N, P, M));``  ``}``}` `// This code is contributed by shikhasingrajput`

## Javascript

 ``

Output

`6`

Time Complexity: O(N*M*P) (Because of three dependent variables)

Auxiliary Space: O(N*M*P) (Size of the DP matrix)

My Personal Notes arrow_drop_up