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 adjacent different 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
Above 4 ways have exactly one pair of adjacent elements with different color.Input: N = 3, M = 3, K = 2
Output: 12
Approach: We can use Dynamic Programming with memoisation to solve the above problem. There are N positions to fill, hence the recursive function will compose 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 same color.
- (m – 1) * countWays(index + 1, cnt + 1), if the next index is filled with a different color. The number of ways get multiplied with (m – 1).
The bases 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 same parameters is done again.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; #define max 4 // Recursive function to find the required number of ways int countWays( int index, int cnt, int dp[][max], int n, int m, int k) { // When all positions are filled if (index == n) { // If adjacent pairs are exactly K if (cnt == k) return 1; else return 0; } // If already calculated if (dp[index][cnt] != -1) return dp[index][cnt]; int 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); return dp[index][cnt] = ans; } // Driver Code int main() { int n = 3, m = 3, k = 2; int dp[n + 1][max]; memset (dp, -1, sizeof dp); cout << m * countWays(1, 0, dp, n, m, k); } |
Java
//Java implementation of the approach class solution { static final int max= 4 ; // Recursive function to find the required number of ways static int countWays( int index, int cnt, int dp[][], int n, int m, int k) { // When all positions are filled if (index == n) { // If adjacent pairs are exactly K if (cnt == k) return 1 ; else return 0 ; } // If already calculated if (dp[index][cnt] != - 1 ) return dp[index][cnt]; int 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); return dp[index][cnt] = ans; } // Driver Code public static void main(String args[]) { int n = 3 , m = 3 , k = 2 ; int dp[][]= new int [n + 1 ][max]; for ( int i= 0 ;i<n+ 1 ;i++) for ( int j= 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 approach max = 4 # Recursive function to find the # required number of ways def countWays(index, cnt, dp, n, m, k): # When all positions are filled if (index = = n) : # If adjacent pairs are exactly K if (cnt = = k): return 1 else : return 0 # 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 if __name__ = = "__main__" : n = 3 m = 3 k = 2 dp = [[ - 1 for x in range (n + 1 )] for y in range ( max )] print (m * countWays( 1 , 0 , dp, n, m, k)) # This code is contributed by ita_c |
C#
// C# implementation of the approach using System; class solution { static int max=4; // Recursive function to find the required number of ways static int countWays( int index, int cnt, int [,]dp, int n, int m, int k) { // When all positions are filled if (index == n) { // If adjacent pairs are exactly K if (cnt == k) return 1; else return 0; } // If already calculated if (dp[index,cnt] != -1) return dp[index,cnt]; int 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); return dp[index,cnt] = ans; } // Driver Code public static void Main() { int n = 3, m = 3, k = 2; int [,]dp= new int [n + 1,max]; for ( int i=0;i<n+1;i++) for ( int j=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 function countWays( $index , $cnt , $dp , $n , $m , $k ) { // When all positions are filled if ( $index == $n ) { // If adjacent pairs are exactly K if ( $cnt == $k ) return 1; else return 0; } // 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 ?> |
12
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.