Given three integers N, M and K. The task is to find the number of ways to fill N positions using M colors such that there are exactly K pairs of different adjacent colors.
Examples:
Input: N = 3, M = 2, K = 1
Output: 4
Let the colors be 1 and 2, so the ways are:
1, 1, 2
1, 2, 2
2, 2, 1
2, 1, 1
The above 4 ways have exactly one pair of adjacent elements with different colors.Input: N = 3, M = 3, K = 2
Output: 12
Approach: We can use Dynamic Programming with memoization to solve the above problem. There are N positions to fill, hence the recursive function will be composed of two calls, one if the next position is filled with the same color and the other if it is filled with a different color. Hence, the recursive calls will be:
- countWays(index + 1, cnt), if the next index is filled with the same color.
- (m – 1) * countWays(index + 1, cnt + 1), if the next index is filled with a different color. The number of ways is multiplied by (m – 1).
The basic cases will be:
- If index = n, then a check for the value of cnt is done. If cnt = K then it is a possible way, hence return 1, else return 0.
- To avoid repetitive calls, memoize the returned value in a 2-D array and return this value if the recursive call with the same parameters is done again.
Below is the implementation of the above approach:
C++
| // C++ implementation of the approach#include <bits/stdc++.h>usingnamespacestd;#define max 4// Recursive function to find the required number of waysintcountWays(intindex, intcnt, intdp[][max], intn, intm, intk){    // When all positions are filled    if(index == n) {        // If adjacent pairs are exactly K        if(cnt == k)            return1;        else            return0;    }    // If already calculated    if(dp[index][cnt] != -1)        returndp[index][cnt];    intans = 0;    // Next position filled with same color    ans += countWays(index + 1, cnt, dp, n, m, k);    // Next position filled with different color    // So there can be m-1 different colors    ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);    returndp[index][cnt] = ans;}// Driver Codeintmain(){    intn = 3, m = 3, k = 2;    intdp[n + 1][max];    memset(dp, -1, sizeofdp);    cout << m * countWays(1, 0, dp, n, m, k);} | 
Java
| //Java implementation of the approachclasssolution{staticfinalintmax=4; // Recursive function to find the required number of waysstaticintcountWays(intindex, intcnt, intdp[][], intn, intm, intk){     // When all positions are filled    if(index == n) {         // If adjacent pairs are exactly K        if(cnt == k)            return1;        else            return0;    }     // If already calculated    if(dp[index][cnt] != -1)        returndp[index][cnt];     intans = 0;     // Next position filled with same color    ans += countWays(index + 1, cnt, dp, n, m, k);     // Next position filled with different color    // So there can be m-1 different colors    ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);     returndp[index][cnt] = ans;} // Driver Codepublicstaticvoidmain(String args[]){    intn = 3, m = 3, k = 2;    intdp[][]= newint[n + 1][max];    for(inti=0;i<n+1;i++)    for(intj=0;j<max;j++)    dp[i][j]=-1;     System.out.println(m * countWays(1, 0, dp, n, m, k));}}//contributed by Arnab Kundu | 
Python 3
| # Python 3 implementation of the approachmax=4# Recursive function to find the # required number of waysdefcountWays(index, cnt, dp, n, m, k):    # When all positions are filled    if(index ==n) :        # If adjacent pairs are exactly K        if(cnt ==k):            return1        else:            return0    # If already calculated    if(dp[index][cnt] !=-1):        returndp[index][cnt]    ans =0    # Next position filled with same color    ans +=countWays(index +1, cnt, dp, n, m, k)    # Next position filled with different color    # So there can be m-1 different colors    ans +=(m -1) *countWays(index +1,                                cnt +1, dp, n, m, k)    dp[index][cnt] =ans    returndp[index][cnt]# Driver Codeif__name__ =="__main__":        n =3    m =3    k =2    dp =[[-1forx inrange(n +1)]               fory inrange(max)]    print(m *countWays(1, 0, dp, n, m, k))# This code is contributed by ita_c | 
C#
| // C# implementation of the approach usingSystem;classsolution { staticintmax=4; // Recursive function to find the required number of ways staticintcountWays(intindex, intcnt, int[,]dp, intn, intm, intk) {     // When all positions are filled     if(index == n) {         // If adjacent pairs are exactly K         if(cnt == k)             return1;         else            return0;     }     // If already calculated     if(dp[index,cnt] != -1)         returndp[index,cnt];     intans = 0;     // Next position filled with same color     ans += countWays(index + 1, cnt, dp, n, m, k);     // Next position filled with different color     // So there can be m-1 different colors     ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);     returndp[index,cnt] = ans; } // Driver Code publicstaticvoidMain() {     intn = 3, m = 3, k = 2;     int[,]dp= newint[n + 1,max];     for(inti=0;i<n+1;i++)         for(intj=0;j<max;j++)             dp[i,j]=-1;     Console.WriteLine(m * countWays(1, 0, dp, n, m, k)); } // This code is contributed by Ryuga}  | 
PHP
| <?php// PHP implementation of the approach $GLOBALS['max'] = 4; // Recursive function to find the // required number of ways functioncountWays($index, $cnt, $dp,                          $n, $m, $k) {     // When all positions are filled     if($index== $n)     {         // If adjacent pairs are exactly K         if($cnt== $k)             return1;         else            return0;     }     // If already calculated     if($dp[$index][$cnt] != -1)         return$dp[$index][$cnt];     $ans= 0;     // Next position filled with same color     $ans+= countWays($index+ 1, $cnt,                       $dp, $n, $m, $k);     // Next position filled with different color     // So there can be m-1 different colors     $ans+= ($m- 1) * countWays($index+ 1, $cnt+ 1,                                  $dp, $n, $m, $k);     $dp[$index][$cnt] = $ans;         return$dp[$index][$cnt];} // Driver Code $n= 3;$m= 3;$k= 2; $dp= array(array());for($i= 0; $i< $n+ 1; $i++)    for($j= 0; $j< $GLOBALS['max']; $j++)        $dp[$i][$j] = -1;echo$m* countWays(1, 0, $dp, $n, $m, $k);// This code is contributed by aishwarya.27?> | 
Javascript
| <script>//Javascript implementation of the approachlet max=4;// Recursive function to find the required number of waysfunctioncountWays(index,cnt,dp,n,m,k){    // When all positions are filled    if(index == n) {           // If adjacent pairs are exactly K        if(cnt == k)            return1;        else            return0;    }       // If already calculated    if(dp[index][cnt] != -1)        returndp[index][cnt];       let ans = 0;       // Next position filled with same color    ans += countWays(index + 1, cnt, dp, n, m, k);       // Next position filled with different color    // So there can be m-1 different colors    ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);       returndp[index][cnt] = ans;}// Driver Codelet n = 3, m = 3, k = 2;let dp=newArray(n+1);for(let i=0;i<n+1;i++){        dp[i]=newArray(max);    for(let j=0;j<max;j++)        dp[i][j]=-1;}    document.write(m * countWays(1, 0, dp, n, m, k));        // This code is contributed by rag2127</script> | 
12
Time Complexity: O(n*4), as we are using recursion and the function will be called N times, where N is the number of positions to be filled.
Auxiliary Space: O(n*4), as we are using extra space for the dp matrix, where N is the number of positions to be filled.
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a DP to store the solution of the subproblems and initialize it with 0.
- Initialize the DP with base cases
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
- Return the final solution stored in m * dp[1][0].
Implementation :
C++
| #include <bits/stdc++.h>usingnamespacestd;#define max 4 intcountWays(intn, intm, intk) {    intdp[n + 1][max];    memset(dp, 0, sizeofdp);     // base case    for(intcnt=0; cnt<=k; cnt++) {        if(cnt == k) {            dp[n][cnt] = 1;        } else{            dp[n][cnt] = 0;        }    }     // fill the table using bottom-up approach    for(intindex=n-1; index>=1; index--) {        for(intcnt=0; cnt<=k; cnt++) {            intans = 0;             // if the current index is not selected            ans += dp[index+1][cnt];             // if the current index is selected            if(cnt+1 <= k) {                ans += (m-1) * dp[index+1][cnt+1];            }             dp[index][cnt] = ans;        }    }     returnm * dp[1][0];} // Driver Codeintmain(){    intn = 3, m = 3, k = 2;    cout << countWays(n, m, k);} | 
Python
| defcountWays(n, m, k):    MAX=4    dp =[[0] *MAXfori inrange(n +1)]     # base case    forcnt inrange(k +1):        ifcnt ==k:            dp[n][cnt] =1        else:            dp[n][cnt] =0     # fill the table using bottom-up approach    forindex inrange(n -1, 0, -1):        forcnt inrange(k +1):            ans =0             # if the current index is not selected            ans +=dp[index +1][cnt]             # if the current index is selected            ifcnt +1<=k:                ans +=(m -1) *dp[index +1][cnt +1]             dp[index][cnt] =ans     returnm *dp[1][0] # Driver Codeif__name__ =="__main__":    n, m, k =3, 3, 2    print(countWays(n, m, k)) | 
Output:
12
Time Complexity: O(n*4)
Auxiliary Space: O(n*4)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







