Given arrays A[] and B[] of size N, the task is to count ways to form an array of size N such that the new array formed has ith element either A[i] or B[i] and adjacent elements are different.
Examples:
Input: A[] = {1, 4, 3}, B[] = {2, 2, 4} Output: 4 Explanation: Possible arrays are {1, 4, 3}, {1, 2, 3}, {1, 2, 4} and {2, 4, 3}. Below is the Recursion Tree. Green is a valid move whereas red is an invalid move.
dp[i][j] represents number of possible arrays of size i with last element chosen from array j (0 for A[] and 1 for B[]).
It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of each state. This can be done by storing the value of a state and whenever the function is called, returning the stored value without computing again.
Follow the steps below to solve the problem:
Declare a dp array, dp[100001][2] initialized with -1 using memset() function.
Create a 2d array Arr[][], whose first column will contain array A[] and the second column will have array B[].
Create a recursive function that takes four parameters i and j such that i represents position and j represents the last element chosen from either A[] or B[], Arr[] stores array A[] and B[], and size of array N.
Calling recursive function recur(0, 0, Arr, N) with i = 0 indicates we will fill the first position of the required array.
Check if i == N, return 1.
Check if dp[i][j] != -1, return dp[i][j].
Initialize variable ans = 0 to count the number of valid solutions.
Call recursive function for both choosing an element from A[] (in this case Arr[][0]) or B[] (in this case Arr[][1]) and add the answer returned to cnt .
Return ans calculated for the current state.
Save the answer in dp[i][j] before returning.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach#include<bits/stdc++.h>usingnamespacestd;// mod to avoid integer overflowconstintmod=1e9+7;// dp tableintdp[100001][2];// recursive Function to count ways to// form array of size N such that adjcent// elements chosen are differentintrecur(inti,intj,vector<vector<int>>&Arr,intN){// If already computed state just// return dp[i][j]if(dp[i][j]!=-1)returndp[i][j];// If array of size N is possibleif(i==N)return1;// Answer initialized with value zerointans=0;// if choosing element from A[]if(i==0orArr[i-1][j]!=Arr[i][0])ans=(ans+recur(i+1,0,Arr,N))%mod;// if choosing element from B[]if(i==0orArr[i-1][j]!=Arr[i][1])ans=(ans+recur(i+1,1,Arr,N))%mod;// Return the final answerreturndp[i][j]=ans;}// Function to count ways to form// array of size N such that adjcent// elements chosen are differentvoidfindWays(intA[],intB[],intN){// initializing dp table with - 1memset(dp,-1,sizeof(dp));// making one array for A[] & B[]vector<vector<int>>Arr(N,vector<int>(2));// filling Arrfor(inti=0;i<N;i++){Arr[i][0]=A[i];Arr[i][1]=B[i];}// calling recursive functioncout<<recur(0,0,Arr,N)<<endl;}// Driver Codeintmain(){// Input 1intA[]={1,4,3},B[]={2,2,4};intN=sizeof(A)/sizeof(A[0]);// Function CallfindWays(A,B,N);// Input 2intA1[]={1,2,3,4},B1[]={5,6,7,8};intN1=sizeof(A1)/sizeof(A1[0]);// Function CallfindWays(A1,B1,N1);return0;}
Java
// Java code to implement the approachimportjava.io.*;importjava.util.*;classGFG{// mod to avoid integer overflowstaticfinalintmod=(int)1e9+7;// dp tablestaticint[][]dp=newint[100001][2];// recursive Function to count ways to form array of// size N such that adjacent elements chosen are// differentstaticintrecur(inti,intj,int[][]Arr,intN){// If already computed state just return dp[i][j]if(dp[i][j]!=-1)returndp[i][j];// If array of size N is possibleif(i==N)return1;// Answer initialized with value zerointans=0;// if choosing element from A[]if(i==0||Arr[i-1][j]!=Arr[i][0])ans=(ans+recur(i+1,0,Arr,N))%mod;// if choosing element from B[]if(i==0||Arr[i-1][j]!=Arr[i][1])ans=(ans+recur(i+1,1,Arr,N))%mod;// Return the final answerreturndp[i][j]=ans;}// Function to count ways to form array of size N such// that adjacent elements chosen are differentstaticvoidfindWays(int[]A,int[]B,intN){// initializing dp table with -1for(inti=0;i<=N;i++){Arrays.fill(dp[i],-1);}// making one array for A[] & B[]int[][]Arr=newint[N][2];// filling Arrfor(inti=0;i<N;i++){Arr[i][0]=A[i];Arr[i][1]=B[i];}// calling recursive functionSystem.out.println(recur(0,0,Arr,N));}publicstaticvoidmain(String[]args){// Input 1int[]A={1,4,3};int[]B={2,2,4};intN=A.length;// Function CallfindWays(A,B,N);// Input 2int[]A1={1,2,3,4};int[]B1={5,6,7,8};intN1=A1.length;// Function CallfindWays(A1,B1,N1);}}// This code is contributed by lokesh.
Python
# python code to implement the approachMOD=int(1e9)+7# dp tabledp=[[-1forjinrange(2)]foriinrange(100001)]# recursive Function to count ways to# form array of size N such that adjacent# elements chosen are differentdefrecur(i,j,arr,N):globaldp# If already computed state just# return dp[i][j]ifdp[i][j]!=-1:returndp[i][j]# If array of size N is possibleifi==N:return1# Answer initialized with value zeroans=0# if choosing element from A[]ifi==0orarr[i-1][j]!=arr[i][0]:ans=(ans+recur(i+1,0,arr,N))%MOD# if choosing element from B[]ifi==0orarr[i-1][j]!=arr[i][1]:ans=(ans+recur(i+1,1,arr,N))%MOD# Return the final answerdp[i][j]=ansreturnans# Function to count ways to form# array of size N such that adjacent# elements chosen are differentdeffindWays(A,B,N):globaldp# making one array for A[] & B[]arr=[[0forjinrange(2)]foriinrange(N)]# filling arrforiinrange(N):arr[i][0]=A[i]arr[i][1]=B[i]# initializing dp table with -1foriinrange(100001):dp[i][0]=dp[i][1]=-1# calling recursive functionprint(recur(0,0,arr,N))# Driver Codeif__name__=='__main__':# Input 1A=[1,4,3]B=[2,2,4]N=len(A)# Function CallfindWays(A,B,N)# Input 2A1=[1,2,3,4]B1=[5,6,7,8]N1=len(A1)# Function CallfindWays(A1,B1,N1)# This code is contributed by lokesh.
C#
// C# code for the approachusingSystem;publicclassGFG{// mod to avoid integer overflowconstintmod=1000000007;// dp tablestaticint[,]dp=newint[100001,2];// recursive Function to count ways to// form array of size N such that adjcent// elements chosen are differentstaticintrecur(inti,intj,int[][]Arr,intN){// If already computed state just// return dp[i][j]if(dp[i,j]!=-1)returndp[i,j];// If array of size N is possibleif(i==N)return1;// Answer initialized with value zerointans=0;// if choosing element from A[]if(i==0||Arr[i-1][j]!=Arr[i][0])ans=(ans+recur(i+1,0,Arr,N))%mod;// if choosing element from B[]if(i==0||Arr[i-1][j]!=Arr[i][1])ans=(ans+recur(i+1,1,Arr,N))%mod;// Return the final answerreturndp[i,j]=ans;}// Function to count ways to form// array of size N such that adjcent// elements chosen are differentstaticvoidfindWays(int[]A,int[]B,intN){// initializing dp table with - 1for(inti=0;i<100001;i++)for(intj=0;j<2;j++)dp[i,j]=-1;// making one array for A[] & B[]int[][]Arr=newint[N][];// filling Arrfor(inti=0;i<N;i++){Arr[i]=newint[2];Arr[i][0]=A[i];Arr[i][1]=B[i];}// calling recursive functionConsole.WriteLine(recur(0,0,Arr,N));}// Driver CodepublicstaticvoidMain(){// Input 1int[]A={1,4,3},B={2,2,4};intN=A.Length;// Function CallfindWays(A,B,N);// Input 2int[]A1={1,2,3,4},B1={5,6,7,8};intN1=A1.Length;// Function CallfindWays(A1,B1,N1);}}
JavaScript
// mod to avoid integer overflowconstmod=1e9+7;// dp tableconstdp=newArray(100001).fill(null).map(()=>newArray(2).fill(-1));// recursive Function to count ways to// form array of size N such that adjacent// elements chosen are differentfunctionrecur(i,j,Arr,N){// If already computed state just// return dp[i][j]if(dp[i][j]!==-1){returndp[i][j];}// If array of size N is possibleif(i===N){return1;}// Answer initialized with value zeroletans=0;// if choosing element from A[]if(i===0||Arr[i-1][j]!==Arr[i][0]){ans=(ans+recur(i+1,0,Arr,N))%mod;}// if choosing element from B[]if(i===0||Arr[i-1][j]!==Arr[i][1]){ans=(ans+recur(i+1,1,Arr,N))%mod;}// Return the final answerreturndp[i][j]=ans;}// Function to count ways to form// array of size N such that adjacent// elements chosen are differentfunctionfindWays(A,B,N){for(leti=0;i<100001;i++){for(letj=0;j<2;j++)dp[i][j]=-1;}// making one array for A[] & B[]constArr=newArray(N).fill(null).map((_,i)=>[A[i],B[i]]);// calling recursive functionconsole.log(recur(0,0,Arr,N));}// Driver Code(functionmain(){// Input 1constA=[1,4,3],B=[2,2,4];constN=A.length;// Function CallfindWays(A,B,N);// Input 2constA1=[1,2,3,4],B1=[5,6,7,8];constN1=A1.length;// Function CallfindWays(A1,B1,N1);})();