Your birthday is coming soon and one of your friends, Alex, is thinking about a gift for you. He knows that you really like integer arrays with interesting properties.
- He selected two numbers, N and K, and decided to write down on paper all integer arrays of length K (in the form a[1], a[2], …, a[K]), where every number a[i] is in the range 1 to N. Moreover, a[i+1] must be divisible by a[i] (for 1 ≤ i < K).
- Alex is very patient, so he managed to do this. Now you need to find how many different arrays are written on the paper. Since the answer can be very large, print the result modulo 10000.
Example:
Input: N = 3, K = 2
Output: 5
Explanation: All possible arrays are: [1, 1], [1, 2], [1, 3], [2, 2], [3, 3].
Table of Content
Naïve Solution - O(n^k) Time and O(1) Space
Generate all possible arrays of length K with elements from 1 to N, check if a[i+1] % a[i] = 0 for 1 ≤ i < K, and count the arrays that satisfy this condition.
#include <iostream>
#include <vector>
using namespace std;
int N, K;
int countArrays = 0;
void generate(vector<int>& arr, int index) {
// If array of length K is formed
if (index == K) {
// Check divisibility condition
for (int i = 0; i < K - 1; i++) {
if (arr[i + 1] % arr[i] != 0)
return; // not valid
}
// If valid, increase count
countArrays++;
return;
}
// Try all numbers from 1 to N
for (int num = 1; num <= N; num++) {
arr[index] = num;
generate(arr, index + 1);
}
}
int main() {
// Input values
N = 3;
K = 2;
vector<int> arr(K);
// Generate all possible arrays
generate(arr, 0);
// Print result
cout << countArrays << endl;
return 0;
}
import java.util.ArrayList;
public class GfG {
int N, K;
int countArrays = 0;
void generate(ArrayList<Integer> arr, int index) {
// If array of length K is formed
if (index == K) {
// Check divisibility condition
for (int i = 0; i < K - 1; i++) {
if (arr.get(i + 1) % arr.get(i) != 0)
return; // not valid
}
// If valid, increase count
countArrays++;
return;
}
// Try all numbers from 1 to N
for (int num = 1; num <= N; num++) {
arr.set(index, num);
generate(arr, index + 1);
}
}
public static void main(String[] args) {
GfG obj = new GfG(); // fixed class object
// Input values
obj.N = 3;
obj.K = 2;
ArrayList<Integer> arr = new ArrayList<>();
// Initialize array
for (int i = 0; i < obj.K; i++) {
arr.add(0);
}
// Generate all possible arrays
obj.generate(arr, 0);
// Print result
System.out.println(obj.countArrays);
}
}
N = 3
K = 2
countArrays = 0
def generate(arr, index):
# If array of length K is formed
if index == K:
# Check divisibility condition
for i in range(K - 1):
if arr[i + 1] % arr[i]!= 0:
return # not valid
# If valid, increase count
global countArrays
countArrays += 1
return
# Try all numbers from 1 to N
for num in range(1, N + 1):
arr[index] = num
generate(arr, index + 1)
# Input values
arr = [0] * K
# Generate all possible arrays
generate(arr, 0)
# Print result
print(countArrays)
using System;
class GfG{
static int N = 3;
static int K = 2;
static int countArrays = 0;
static void Generate(int[] arr, int index)
{
// If array of length K is formed
if (index == K)
{
// Check divisibility condition
for (int i = 0; i < K - 1; i++)
{
if (arr[i + 1] % arr[i]!= 0)
return; // not valid
}
// If valid, increase count
countArrays++;
return;
}
// Try all numbers from 1 to N
for (int num = 1; num <= N; num++)
{
arr[index] = num;
Generate(arr, index + 1);
}
}
static void Main()
{
// Input values
int[] arr = new int[K];
// Generate all possible arrays
Generate(arr, 0);
// Print result
Console.WriteLine(countArrays);
}
}
let N = 3, K = 2;
let countArrays = 0;
function generate(arr, index) {
// If array of length K is formed
if (index === K) {
// Check divisibility condition
for (let i = 0; i < K - 1; i++) {
if (arr[i + 1] % arr[i]!== 0)
return; // not valid
}
// If valid, increase count
countArrays++;
return;
}
// Try all numbers from 1 to N
for (let num = 1; num <= N; num++) {
arr[index] = num;
generate(arr, index + 1);
}
}
// driver code
let arr = new Array(K).fill(0);
generate(arr, 0);
console.log(countArrays);
Efficient Approach (Dynamic Programming) - O(n^2 * log(k)) Time and O(1) Space
- Use a DP table where dp[i][j] represents the number of valid arrays of length i ending with value j.
- Initialize the base case: for arrays of length 1, every number from 1 to N can appear once.
- For each length from 2 to K, update the table by adding values from previous elements that divide the current element.
- Finally, sum all values in dp[K][j] for 1 ≤ j ≤ N and return the result modulo 10000.
#include <iostream>
#include <vector>
using namespace std;
int countValidArrays(int n, int k)
{
// dp[i][j] represents the number of valid arrays of
// length i ending with element j
vector<vector<int> > dp(k + 1, vector<int>(n + 1, 0));
// Base case: There are 'n' arrays of length 1, each
// ending with a different number from 1 to 'n'
for (int j = 1; j <= n; j++) {
dp[1][j] = 1;
}
// Fill the dp array
for (int len = 2; len <= k; len++) {
for (int end = 1; end <= n; end++) {
for (int prev = 1; prev <= n; prev++) {
if (end % prev == 0) {
dp[len][end] += dp[len - 1][prev];
}
}
}
}
// Sum up all valid arrays of length 'k'
int result = 0;
for (int j = 1; j <= n; j++) {
result += dp[k][j];
}
return result;
}
int main()
{
// Input values for 'n' and 'k'
int n = 3;
int k = 2;
// Calculate and print the number of different arrays
cout << countValidArrays(n, k) << endl;
return 0;
}
public class GfG{
public static int CountValidArrays(int n, int k) {
int[][] dp = new int[k + 1][n + 1];
// Base case: There are 'n' arrays of length 1, each
// ending with a different number from 1 to 'n'
for (int j = 1; j <= n; j++) {
dp[1][j] = 1;
}
// Fill the dp array
for (int len = 2; len <= k; len++) {
for (int end = 1; end <= n; end++) {
for (int prev = 1; prev <= n; prev++) {
if (end % prev == 0) {
dp[len][end] += dp[len - 1][prev];
}
}
}
}
// Sum up all valid arrays of length 'k'
int result = 0;
for (int j = 1; j <= n; j++) {
result += dp[k][j];
}
return result;
}
public static void main(String[] args) {
// Input values for 'n' and 'k'
int n = 3;
int k = 2;
// Calculate and print the number of different
// arrays
System.out.println(CountValidArrays(n, k));
}
}
def CountValidArrays(n, k):
dp = [[0 for _ in range(n + 1)] for _ in range(k + 1)]
# Base case: arrays of length 1
for j in range(1, n + 1):
dp[1][j] = 1
# Fill the DP table
for length in range(2, k + 1):
for end in range(1, n + 1):
for prev in range(1, n + 1):
if end % prev == 0:
dp[length][end] += dp[length - 1][prev]
# Count arrays of length k
result = 0
for j in range(1, n + 1):
result += dp[k][j]
return result
if __name__ == "__main__":
# Input values
n = 3
k = 2
# Print result
print(CountValidArrays(n, k))
using System;
class GfG{
public static int CountValidArrays(int n, int k)
{
int[, ] dp = new int[k + 1, n + 1];
// Base case: There are 'n' arrays of length 1, each
// ending with a different number from 1 to 'n'
for (int j = 1; j <= n; j++) {
dp[1, j] = 1;
}
// Fill the dp array
for (int len = 2; len <= k; len++) {
for (int end = 1; end <= n; end++) {
for (int prev = 1; prev <= n; prev++) {
if (end % prev == 0) {
dp[len, end] += dp[len - 1, prev];
}
}
}
}
// Sum up all valid arrays of length 'k'
int result = 0;
for (int j = 1; j <= n; j++) {
result += dp[k, j];
}
return result;
}
static void Main(string[] args)
{
// Input values for 'n' and 'k'
int n = 3;
int k = 2;
// Calculate and print the number of different
// arrays
Console.WriteLine(CountValidArrays(n, k));
}
}
function CountValidArrays(n, k) {
let dp = new Array(k + 1).fill(0).map(() => new Array(n + 1).fill(0));
// Base case: arrays of length 1
for (let j = 1; j <= n; j++) {
dp[1][j] = 1;
}
// Fill the dp array
for (let len = 2; len <= k; len++) {
for (let end = 1; end <= n; end++) {
for (let prev = 1; prev <= n; prev++) {
if (end % prev === 0) {
dp[len][end] += dp[len - 1][prev];
}
}
}
}
// Sum arrays of length k
let result = 0;
for (let j = 1; j <= n; j++) {
result += dp[k][j];
}
return result;
}
// Driver code
let n = 3;
let k = 2;
console.log(CountValidArrays(n, k));
Output
5