Ways to fill N positions using M colors such that there are exactly K pairs of adjacent different colors
Last Updated :
04 Dec, 2023
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++
#include <bits/stdc++.h>
using namespace std;
#define max 4
int countWays( int index, int cnt, int dp[][max], int n, int m, int k)
{
if (index == n) {
if (cnt == k)
return 1;
else
return 0;
}
if (dp[index][cnt] != -1)
return dp[index][cnt];
int ans = 0;
ans += countWays(index + 1, cnt, dp, n, m, k);
ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);
return dp[index][cnt] = ans;
}
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
class solution
{
static final int max= 4 ;
static int countWays( int index, int cnt, int dp[][], int n, int m, int k)
{
if (index == n) {
if (cnt == k)
return 1 ;
else
return 0 ;
}
if (dp[index][cnt] != - 1 )
return dp[index][cnt];
int ans = 0 ;
ans += countWays(index + 1 , cnt, dp, n, m, k);
ans += (m - 1 ) * countWays(index + 1 , cnt + 1 , dp, n, m, k);
return dp[index][cnt] = ans;
}
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));
}
}
|
Python 3
max = 4
def countWays(index, cnt, dp, n, m, k):
if (index = = n) :
if (cnt = = k):
return 1
else :
return 0
if (dp[index][cnt] ! = - 1 ):
return dp[index][cnt]
ans = 0
ans + = countWays(index + 1 , cnt, dp, n, m, k)
ans + = (m - 1 ) * countWays(index + 1 ,
cnt + 1 , dp, n, m, k)
dp[index][cnt] = ans
return dp[index][cnt]
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))
|
C#
using System;
class solution
{
static int max=4;
static int countWays( int index, int cnt, int [,]dp, int n, int m, int k)
{
if (index == n) {
if (cnt == k)
return 1;
else
return 0;
}
if (dp[index,cnt] != -1)
return dp[index,cnt];
int ans = 0;
ans += countWays(index + 1, cnt, dp, n, m, k);
ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);
return dp[index,cnt] = ans;
}
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));
}
}
|
Javascript
<script>
let max=4;
function countWays(index,cnt,dp,n,m,k)
{
if (index == n) {
if (cnt == k)
return 1;
else
return 0;
}
if (dp[index][cnt] != -1)
return dp[index][cnt];
let ans = 0;
ans += countWays(index + 1, cnt, dp, n, m, k);
ans += (m - 1) * countWays(index + 1, cnt + 1, dp, n, m, k);
return dp[index][cnt] = ans;
}
let n = 3, m = 3, k = 2;
let dp= new Array(n+1);
for (let i=0;i<n+1;i++)
{
dp[i]= new Array(max);
for (let j=0;j<max;j++)
dp[i][j]=-1;
}
document.write(m * countWays(1, 0, dp, n, m, k));
</script>
|
PHP
<?php
$GLOBALS [ 'max' ] = 4;
function countWays( $index , $cnt , $dp ,
$n , $m , $k )
{
if ( $index == $n )
{
if ( $cnt == $k )
return 1;
else
return 0;
}
if ( $dp [ $index ][ $cnt ] != -1)
return $dp [ $index ][ $cnt ];
$ans = 0;
$ans += countWays( $index + 1, $cnt ,
$dp , $n , $m , $k );
$ans += ( $m - 1) * countWays( $index + 1, $cnt + 1,
$dp , $n , $m , $k );
$dp [ $index ][ $cnt ] = $ans ;
return $dp [ $index ][ $cnt ];
}
$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 );
?>
|
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>
using namespace std;
#define max 4
int countWays( int n, int m, int k) {
int dp[n + 1][max];
memset (dp, 0, sizeof dp);
for ( int cnt=0; cnt<=k; cnt++) {
if (cnt == k) {
dp[n][cnt] = 1;
} else {
dp[n][cnt] = 0;
}
}
for ( int index=n-1; index>=1; index--) {
for ( int cnt=0; cnt<=k; cnt++) {
int ans = 0;
ans += dp[index+1][cnt];
if (cnt+1 <= k) {
ans += (m-1) * dp[index+1][cnt+1];
}
dp[index][cnt] = ans;
}
}
return m * dp[1][0];
}
int main()
{
int n = 3, m = 3, k = 2;
cout << countWays(n, m, k);
}
|
Java
import java.util.Arrays;
public class Main {
static int max = 4 ;
static int countWays( int n, int m, int k) {
int [][] dp = new int [n + 1 ][max];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
for ( int cnt = 0 ; cnt <= k; cnt++) {
if (cnt == k) {
dp[n][cnt] = 1 ;
} else {
dp[n][cnt] = 0 ;
}
}
for ( int index = n - 1 ; index >= 1 ; index--) {
for ( int cnt = 0 ; cnt <= k; cnt++) {
int ans = 0 ;
ans += dp[index + 1 ][cnt];
if (cnt + 1 <= k) {
ans += (m - 1 ) * dp[index + 1 ][cnt + 1 ];
}
dp[index][cnt] = ans;
}
}
return m * dp[ 1 ][ 0 ];
}
public static void main(String[] args) {
int n = 3 , m = 3 , k = 2 ;
System.out.println(countWays(n, m, k));
}
}
|
Python
def countWays(n, m, k):
MAX = 4
dp = [[ 0 ] * MAX for i in range (n + 1 )]
for cnt in range (k + 1 ):
if cnt = = k:
dp[n][cnt] = 1
else :
dp[n][cnt] = 0
for index in range (n - 1 , 0 , - 1 ):
for cnt in range (k + 1 ):
ans = 0
ans + = dp[index + 1 ][cnt]
if cnt + 1 < = k:
ans + = (m - 1 ) * dp[index + 1 ][cnt + 1 ]
dp[index][cnt] = ans
return m * dp[ 1 ][ 0 ]
if __name__ = = "__main__" :
n, m, k = 3 , 3 , 2
print (countWays(n, m, k))
|
C#
using System;
class WaysCount
{
const int Max = 4;
static int CountWays( int n, int m, int k)
{
int [,] dp = new int [n + 1, Max];
for ( int cnt = 0; cnt <= k; cnt++)
{
if (cnt == k)
{
dp[n, cnt] = 1;
}
else
{
dp[n, cnt] = 0;
}
}
for ( int index = n - 1; index >= 1; index--)
{
for ( int cnt = 0; cnt <= k; cnt++)
{
int ans = 0;
ans += dp[index + 1, cnt];
if (cnt + 1 <= k)
{
ans += (m - 1) * dp[index + 1, cnt + 1];
}
dp[index, cnt] = ans;
}
}
return m * dp[1, 0];
}
static void Main()
{
int n = 3, m = 3, k = 2;
Console.WriteLine( "Number of ways: " + CountWays(n, m, k));
}
}
|
Javascript
function countWays(n, m, k) {
let dp = new Array(n + 1).fill(0).map(() => new Array(4).fill(0));
for (let cnt = 0; cnt <= k; cnt++) {
if (cnt === k) {
dp[n][cnt] = 1;
} else {
dp[n][cnt] = 0;
}
}
for (let index = n - 1; index >= 1; index--) {
for (let cnt = 0; cnt <= k; cnt++) {
let ans = 0;
ans += dp[index + 1][cnt];
if (cnt + 1 <= k) {
ans += (m - 1) * dp[index + 1][cnt + 1];
}
dp[index][cnt] = ans;
}
}
return m * dp[1][0];
}
let n = 3, m = 3, k = 2;
console.log(countWays(n, m, k));
|
Output:
12
Time Complexity: O(n*4)
Auxiliary Space: O(n*4)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...