Given two positive integer n and n. The task is to find the number of arrays of size n that can be formed such that :
- Each element is in range [1, m]
- All adjacent element are such that one of them divide the another i.e element Ai divides Ai + 1 or Ai + 1 divides Ai + 2.
Examples:
Input : n = 3, m = 3.
Output : 17
{1,1,1}, {1,1,2}, {1,1,3}, {1,2,1},
{1,2,2}, {1,3,1}, {1,3,3}, {2,1,1},
{2,1,2}, {2,1,3}, {2,2,1}, {2,2,2},
{3,1,1}, {3,1,2}, {3,1,3}, {3,3,1},
{3,3,3} are possible arrays.
Input : n = 1, m = 10.
Output : 10
We try to find number of possible values at each index of the array. First, at index 0 all values are possible from 1 to m. Now observe for each index, we can reach either to its multiple or its factor. So, precompute that and store it for all the elements. Hence for each position i, ending with integer x, we can go to next position i + 1, with the array ending in integer with multiple of x or factor of x. Also, multiple of x or factor of x must be less than m.
So, we define an 2D array dp[i][j], which is number of possible array (divisible adjacent element) of size i with j as its first index element.
1 <= i <= m, dp[1][m] = 1.
for 1 <= j <= m and 2 <= i <= n
dp[i][j] = dp[i-1][j] + number of factor
of previous element less than m
+ number of multiples of previous
element less than m.
Below is the implementation of this approach:
C++
// C++ program to count number of arrays // of size n such that every element is // in range [1, m] and adjacen are // divisible #include <bits/stdc++.h> #define MAX 1000 using namespace std; int numofArray(int n, int m) { int dp[MAX][MAX]; // For storing factors. vector<int> di[MAX]; // For storing multiples. vector<int> mu[MAX]; memset(dp, 0, sizeof dp); memset(di, 0, sizeof di); memset(mu, 0, sizeof mu); // calculating the factors and multiples // of elements [1...m]. for (int i = 1; i <= m; i++) { for (int j = 2*i; j <= m; j += i) { di[j].push_back(i); mu[i].push_back(j); } di[i].push_back(i); } // Initalising for size 1 array for // each i <= m. for (int i = 1; i <= m; i++) dp[1][i] = 1; // Calculating the number of array possible // of size i and starting with j. for (int i = 2; i <= n; i++) { for (int j = 1; j <= m; j++) { dp[i][j] = 0; // For all previous possible values. // Adding number of factors. for (auto x:di[j]) dp[i][j] += dp[i-1][x]; // Adding number of multiple. for (auto x:mu[j]) dp[i][j] += dp[i-1][x]; } } // Calculating the total count of array // which start from [1...m]. int ans = 0; for (int i = 1; i <= m; i++) { ans += dp[n][i]; di[i].clear(); mu[i].clear(); } return ans; } // Driven Program int main() { int n = 3, m = 3; cout << numofArray(n, m) << "\n"; return 0; } |
Java
// Java program to count number of arrays // of size n such that every element is // in range [1, m] and adjacen are // divisible import java.util.*; class GFG { static int MAX = 1000; static int numofArray(int n, int m) { int [][]dp = new int[MAX][MAX]; // For storing factors. Vector<Integer> []di = new Vector[MAX]; // For storing multiples. Vector<Integer> []mu = new Vector[MAX]; for(int i = 0; i < MAX; i++) { for(int j = 0; j < MAX; j++) { dp[i][j] = 0; } } for(int i = 0; i < MAX; i++) { di[i] = new Vector<>(); mu[i] = new Vector<>(); } // calculating the factors and multiples // of elements [1...m]. for (int i = 1; i <= m; i++) { for (int j = 2 * i; j <= m; j += i) { di[j].add(i); mu[i].add(j); } di[i].add(i); } // Initalising for size 1 array for // each i <= m. for (int i = 1; i <= m; i++) dp[1][i] = 1; // Calculating the number of array possible // of size i and starting with j. for (int i = 2; i <= n; i++) { for (int j = 1; j <= m; j++) { dp[i][j] = 0; // For all previous possible values. // Adding number of factors. for (Integer x:di[j]) dp[i][j] += dp[i - 1][x]; // Adding number of multiple. for (Integer x:mu[j]) dp[i][j] += dp[i - 1][x]; } } // Calculating the total count of array // which start from [1...m]. int ans = 0; for (int i = 1; i <= m; i++) { ans += dp[n][i]; di[i].clear(); mu[i].clear(); } return ans; } // Driver Code public static void main(String[] args) { int n = 3, m = 3; System.out.println(numofArray(n, m)); } } // This code is contributed by 29AjayKumar |
Python3
# Python3 program to count the number of # arrays of size n such that every element is # in range [1, m] and adjacent are divisible MAX = 1000 def numofArray(n, m): dp = [[0 for i in range(MAX)] for j in range(MAX)] # For storing factors. di = [[] for i in range(MAX)] # For storing multiples. mu = [[] for i in range(MAX)] # calculating the factors and multiples # of elements [1...m]. for i in range(1, m+1): for j in range(2*i, m+1, i): di[j].append(i) mu[i].append(j) di[i].append(i) # Initalising for size 1 array for each i <= m. for i in range(1, m+1): dp[1][i] = 1 # Calculating the number of array possible # of size i and starting with j. for i in range(2, n+1): for j in range(1, m+1): dp[i][j] = 0 # For all previous possible values. # Adding number of factors. for x in di[j]: dp[i][j] += dp[i-1][x] # Adding number of multiple. for x in mu[j]: dp[i][j] += dp[i-1][x] # Calculating the total count of array # which start from [1...m]. ans = 0 for i in range(1, m+1): ans += dp[n][i] di[i].clear() mu[i].clear() return ans # Driven Program if __name__ == "__main__": n = m = 3 print(numofArray(n, m)) # This code is contributed by Rituraj Jain |
C#
// C# program to count number of arrays // of size n such that every element is // in range [1, m] and adjacen are // divisible using System; using System.Collections.Generic; class GFG { static int MAX = 1000; static int numofArray(int n, int m) { int [,]dp = new int[MAX, MAX]; // For storing factors. List<int> []di = new List<int>[MAX]; // For storing multiples. List<int> []mu = new List<int>[MAX]; for(int i = 0; i < MAX; i++) { for(int j = 0; j < MAX; j++) { dp[i, j] = 0; } } for(int i = 0; i < MAX; i++) { di[i] = new List<int>(); mu[i] = new List<int>(); } // calculating the factors and multiples // of elements [1...m]. for (int i = 1; i <= m; i++) { for (int j = 2 * i; j <= m; j += i) { di[j].Add(i); mu[i].Add(j); } di[i].Add(i); } // Initalising for size 1 array for // each i <= m. for (int i = 1; i <= m; i++) dp[1, i] = 1; // Calculating the number of array possible // of size i and starting with j. for (int i = 2; i <= n; i++) { for (int j = 1; j <= m; j++) { dp[i, j] = 0; // For all previous possible values. // Adding number of factors. foreach (int x in di[j]) dp[i, j] += dp[i - 1, x]; // Adding number of multiple. foreach (int x in mu[j]) dp[i, j] += dp[i - 1, x]; } } // Calculating the total count of array // which start from [1...m]. int ans = 0; for (int i = 1; i <= m; i++) { ans += dp[n, i]; di[i].Clear(); mu[i].Clear(); } return ans; } // Driver Code public static void Main(String[] args) { int n = 3, m = 3; Console.WriteLine(numofArray(n, m)); } } // This code is contributed by Princi Singh |
Output:
17
Time Complexity: O(N*M).
This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
- Number of ways to divide string in sub-strings such to make them in lexicographically increasing sequence
- Longest subsequence such that adjacent elements have at least one common digit
- Maximum subset sum such that no two elements in set have same digit in them
- Find length of longest subsequence of one string which is substring of another string
- GCD of two numbers when one of them can be very large
- Maximum sum in an array such that every element has exactly one adjacent element to it
- Print all possible ways to convert one string into another string | Edit-Distance
- Count of all subsequences having adjacent elements with different parity
- Count of strings where adjacent characters are of difference one
- Minimize elements to be added to a given array such that it contains another given array as its subsequence
- Product of all sorted subsets of size K using elements whose index divide K completely
- Maximum sum such that no two elements are adjacent
- Maximum sum in a 2 x n grid such that no two elements are adjacent
- Maximum sum in circular array such that no two elements are adjacent
- Maximum length subsequence such that adjacent elements in the subsequence have a common factor
- Length of the longest increasing subsequence such that no two adjacent elements are coprime
- Maximum sum such that no two elements are adjacent | Set 2
- Maximum sub-sequence sum such that indices of any two adjacent elements differs at least by 3
- Length of the longest subsequence such that xor of adjacent elements is non-decreasing
- Maximum sum such that exactly half of the elements are selected and no two adjacent

