Count the number of arrays formed by rearranging elements such that one adjacent element is multiple of other
Last Updated :
18 Jan, 2024
Given array A[] of size N (1 <= N <= 15), count all possible arrays formed by rearranging elements of A[] such that at least one of the following conditions is true for adjacent elements of that array:
- A[i] % A[i + 1] == 0
- A[i + 1] % A[i] == 0
The count can be a large, modulo answer with 109+ 7 before printing.
Examples:
Input: A[] = {2, 3, 6}
Output: 2
Explanation: {3, 6, 2} and {2, 6, 3} are two possible rearrangement of array A[] such that one of the required conditions satisfy for adjacent elements.
Input: A[] = {1, 4, 3}
Output: 2
Explanation: {3, 1, 4} and {4, 1, 3} are two possible rearrangement of array A[] such that one of the required conditions satisfy for adjacent elements.
Approach: Implement the idea below to solve the problem
Bitmask Dynamic Programming can be used to solve this problem. The main concept of DP in the problem will be:
DP[i][j] represents count of arrangements which satisfy above conditions where i represents subset in form of bitmask and j represents last element of this subset so to check divisibility conditions when new element will be added in subset i.
Transition:
dp[i | (1 << (k – 1))][k] = (dp[i | (1 << (k – 1))][k] + dp[i][j])
here k is kth element of array A[] being added at the end of the subset i whose last element is j’th of array A[]
Steps were taken to solve the problem:
- Declaring DP[1 << N][N + 1] array.
- Initializing the base case by iterating over 0 to N – 1 as i, then set dp[1 << i][i + 1] = 1
- Iterating over all subsets from 1 to 2N as i and for each iteration
- Iterate from 1 to N as j if the j’th bit of subset i is not set then it means that jth element is not considered in the current submask, so we skip that iteration.
- Else, Iterate from 1 to N as k and for each iteration and check if the k’th bit is not in the current submask and last element j and k satisfy required condition, then update dp table according to transitions: dp[i | (1 << (k – 1))][k] = (dp[i | (1 << (k – 1))][k] + dp[i][j])
- After iterating over all the submasks, add dp[(1 << N) – 1][i] which represents count of arrangement of size N with last element i which satisfies the above conditions.
- Return ans.
Code to implement the approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int countOfArr( int A[], int N)
{
vector<vector< int > > dp((1 << (N + 1)),
vector< int >(N + 2, 0));
for ( int i = 0; i < N; i++)
dp[1 << i][i + 1] = 1;
for ( int i = 1; i < (1 << N); i++) {
for ( int j = 1; j <= N; j++) {
if (((1 << (j - 1)) & i) == 0)
continue ;
for ( int k = 1; k <= N; k++) {
if (((1 << (k - 1)) & i) == 0
and (A[j - 1] % A[k - 1] == 0
or A[k - 1] % A[j - 1] == 0)) {
dp[i | (1 << (k - 1))][k]
= (dp[i | (1 << (k - 1))][k]
+ dp[i][j])
% mod;
}
}
}
}
int ans = 0;
for ( int i = 1; i <= N; i++) {
ans = (ans + dp[(1 << N) - 1][i]) % mod;
}
return ans;
}
int32_t main()
{
int N = 3;
int A[] = { 2, 3, 6 };
cout << countOfArr(A, N) << endl;
return 0;
}
|
Java
class GFG {
static int count_of_arr( int A[], int N) {
int mod = ( int ) (1e9 + 7 );
int [][] dp = new int [ 1 << (N + 1 )][N + 2 ];
for ( int i = 0 ; i < N; i++) {
dp[ 1 << i][i + 1 ] = 1 ;
}
for ( int i = 1 ; i < ( 1 << N); i++) {
for ( int j = 1 ; j <= N; j++) {
if ((i & ( 1 << (j - 1 ))) == 0 ) {
continue ;
}
for ( int k = 1 ; k <= N; k++) {
if ((i & ( 1 << (k - 1 ))) == 0 && (A[j - 1 ] % A[k - 1 ] == 0 || A[k - 1 ] % A[j - 1 ] == 0 )) {
dp[i | ( 1 << (k - 1 ))][k] = (dp[i | ( 1 << (k - 1 ))][k] + dp[i][j]) % mod;
}
}
}
}
int ans = 0 ;
for ( int i = 1 ; i <= N; i++) {
ans = (ans + dp[( 1 << N) - 1 ][i]) % mod;
}
return ans;
}
public static void main(String[] args) {
int N = 3 ;
int [] A = { 2 , 3 , 6 };
System.out.println(count_of_arr(A, N));
}
}
|
Python3
def count_of_arr(A, N):
mod = 10 * * 9 + 7
dp = [[ 0 ] * (N + 2 ) for _ in range ( 1 << (N + 1 ))]
for i in range (N):
dp[ 1 << i][i + 1 ] = 1
for i in range ( 1 , 1 << N):
for j in range ( 1 , N + 1 ):
if not ( 1 << (j - 1 )) & i:
continue
for k in range ( 1 , N + 1 ):
if not ( 1 << (k - 1 )) & i and (A[j - 1 ] % A[k - 1 ] = = 0 or A[k - 1 ] % A[j - 1 ] = = 0 ):
dp[i | ( 1 << (k - 1 ))][k] = (dp[i | ( 1 << (k - 1 ))]
[k] + dp[i][j]) % mod
ans = 0
for i in range ( 1 , N + 1 ):
ans = (ans + dp[( 1 << N) - 1 ][i]) % mod
return ans
if __name__ = = "__main__" :
N = 3
A = [ 2 , 3 , 6 ]
print (count_of_arr(A, N))
|
C#
using System;
class GFG {
const int mod = 1000000007;
static int countOfArr( int [] A, int N) {
var dp = new int [1 << (N + 1), N + 2];
for ( int i = 0; i < N; i++)
dp[1 << i, i + 1] = 1;
for ( int i = 1; i < (1 << N); i++) {
for ( int j = 1; j <= N; j++) {
if (((1 << (j - 1)) & i) == 0)
continue ;
for ( int k = 1; k <= N; k++) {
if (((1 << (k - 1)) & i) == 0 &&
(A[j - 1] % A[k - 1] == 0 || A[k - 1] % A[j - 1] == 0)) {
dp[i | (1 << (k - 1)), k] = (dp[i | (1 << (k - 1)), k] + dp[i, j]) % mod;
}
}
}
}
int ans = 0;
for ( int i = 1; i <= N; i++) {
ans = (ans + dp[(1 << N) - 1, i]) % mod;
}
return ans;
}
static void Main() {
int N = 3;
int [] A = { 2, 3, 6 };
Console.WriteLine(countOfArr(A, N));
}
}
|
Javascript
function countOfArr(A, N) {
const mod = 10**9 + 7;
const dp = Array.from({ length: 1 << (N + 1) },
() => Array(N + 2).fill(0));
for (let i = 0; i < N; i++) {
dp[1 << i][i + 1] = 1;
}
for (let i = 1; i < 1 << N; i++) {
for (let j = 1; j <= N; j++) {
if (!((1 << (j - 1)) & i)) {
continue ;
}
for (let k = 1; k <= N; k++) {
if ( !((1 << (k - 1)) & i) &&
(A[j - 1] % A[k - 1] === 0 || A[k - 1] % A[j - 1] === 0)) {
dp[i | (1 << (k - 1))][k] =
(dp[i | (1 << (k - 1))][k] + dp[i][j]) % mod;
}
}
}
}
let ans = 0;
for (let i = 1; i <= N; i++) {
ans = (ans + dp[(1 << N) - 1][i]) % mod;
}
return ans;
}
const N = 3;
const A = [2, 3, 6];
console.log(countOfArr(A, N));
|
Time Complexity: O(N2 * 2N), where N is the size of input array A[].
Auxiliary Space: O(N * 2N)
Share your thoughts in the comments
Please Login to comment...