Open In App

Ways to arrange Balls such that adjacent balls are of different types

Last Updated : 15 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

There are ‘p’ balls of type P, ‘q’ balls of type Q and ‘r’ balls of type R. Using the balls we want to create a straight line such that no two balls of same type are adjacent.
Examples : 

Input  : p = 1, q = 1, r = 0
Output : 2
There are only two arrangements PQ and QP
Input  : p = 1, q = 1, r = 1
Output : 6
There are only six arrangements PQR, QPR,
QRP, RQP, PRQ and RPQ
Input  : p = 2, q = 1, r = 1
Output : 12
There are twelve arrangements PQRP, PRQP, QPRP, RPQP, PQPR, PRPQ 
QPQR, RQRP, PQRQ, QRQP, RPQR, and QRPR

We strongly recommend that you click here and practice it, before moving on to the solution.


Naive Solution: 
The naive solution to this problem is a recursive solution. We recursively call for three cases 
1) Last ball to be placed is of type P 
2) Last ball to be placed is of type Q 
3) Last ball to be placed is of type R
Below is the implementation of above idea. 
 

C++
// C++ program to count number of ways to arrange three
// types of balls such that no two balls of same color
// are adjacent to each other
#include<bits/stdc++.h>
using namespace std;

// Returns count of arrangements where last placed ball is
// 'last'.  'last' is 0 for 'p', 1 for 'q' and 2 for 'r'
int countWays(int p, int q, int r, int last)
{
    // if number of balls of any color becomes less
    // than 0 the number of ways arrangements is 0.
    if (p<0 || q<0 || r<0)
        return 0;

    // If last ball required is of type P and the number
    // of balls of P type is 1 while number of balls of
    // other color is 0 the number of ways is 1.
    if (p==1 && q==0 && r==0 && last==0)
        return 1;

    // Same case as above for 'q' and 'r'
    if (p==0 && q==1 && r==0 && last==1)
        return 1;
    if (p==0 && q==0 && r==1 && last==2)
        return 1;

    // if last ball required is P and the number of ways is
    // the sum of number of ways to form sequence with 'p-1' P
    // balls, q Q Balls and r R balls ending with Q and R.
    if (last==0)
        return countWays(p-1,q,r,1) + countWays(p-1,q,r,2);

    // Same as above case for 'q' and 'r'
    if (last==1)
        return countWays(p,q-1,r,0) + countWays(p,q-1,r,2);
    if (last==2)
        return countWays(p,q,r-1,0) + countWays(p,q,r-1,1);
}

// Returns count of required arrangements
int countUtil(int p, int q, int r)
{
   // Three cases arise:
   return countWays(p, q, r, 0) +  // Last required balls is type P
          countWays(p, q, r, 1) +  // Last required balls is type Q
          countWays(p, q, r, 2); // Last required balls is type R
}

// Driver code to test above
int main()
{
    int p = 1, q = 1, r = 1;
    printf("%d", countUtil(p, q, r));
    return 0;
}
Java
// Java program to count number
// of ways to arrange three types of
// balls such that no two balls of
// same color are adjacent to each other
import java.io.*;
import java.util.*;

class GFG {

    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p',
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q, int r, int last)
    {
        // if number of balls of any
        // color becomes less than 0
        // the number of ways arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
            return 0;

        // If last ball required is
        // of type P and the number
        // of balls of P type is 1
        // while number of balls of
        // other color is 0 the number
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 && last == 0)
            return 1;

        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 && last == 1)
            return 1;
        if (p == 0 && q == 0 && r == 1 && last == 2)
            return 1;

        // if last ball required is P
        // and the number of ways is
        // the sum of number of ways
        // to form sequence with 'p-1' P
        // balls, q Q Balls and r R balls
        // ending with Q and R.
        if (last == 0)
            return countWays(p - 1, q, r, 1)
                + countWays(p - 1, q, r, 2);

        // Same as above case for 'q' and 'r'
        if (last == 1)
            return countWays(p, q - 1, r, 0)
                + countWays(p, q - 1, r, 2);

        if (last == 2)
            return countWays(p, q, r - 1, 0)
                + countWays(p, q, r - 1, 1);

        return 0;
    }

    // Returns count of required arrangements
    static int countUtil(int p, int q, int r)
    {
        // Three cases arise:
        return countWays(p, q, r, 0)
            + // Last required balls is type P
            countWays(p, q, r, 1)
            + // Last required balls is type Q
            countWays(p, q, r,
                      2); // Last required balls is type R
    }

    // Driver code
    public static void main(String[] args)
    {
        int p = 1, q = 1, r = 1;
        System.out.print(countUtil(p, q, r));
    }
}

// This code is contributed by Anant Agarwal.
Python3
# Python3 program to count 
# number of ways to arrange 
# three types of balls such  
# that no two balls of same 
# color are adjacent to each 
# other

# Returns count of arrangements
# where last placed ball is
# 'last'. 'last' is 0 for 'p',
# 1 for 'q' and 2 for 'r'
def countWays(p, q, r, last):
    
    # if number of balls of 
    # any color becomes less
    # than 0 the number of 
    # ways arrangements is 0.
    if (p < 0 or q < 0 or r < 0):
        return 0;

    # If last ball required is
    # of type P and the number
    # of balls of P type is 1
    # while number of balls of
    # other color is 0 the number
    # of ways is 1.
    if (p == 1 and q == 0 and
        r == 0 and last == 0):
        return 1;

    # Same case as above 
    # for 'q' and 'r'
    if (p == 0 and q == 1 and
        r == 0 and last == 1):
        return 1;
        
    if (p == 0 and q == 0 and 
        r == 1 and last == 2):
        return 1;

    # if last ball required is P 
    # and the number of ways is
    # the sum of number of ways 
    # to form sequence with 'p-1' P
    # balls, q Q Balls and r R 
    # balls ending with Q and R.
    if (last == 0):
        return (countWays(p - 1, q, r, 1) + 
                countWays(p - 1, q, r, 2));

    # Same as above case
    # for 'q' and 'r'
    if (last == 1):
        return (countWays(p, q - 1, r, 0) + 
                countWays(p, q - 1, r, 2));
    if (last == 2):
        return (countWays(p, q, r - 1, 0) + 
                countWays(p, q, r - 1, 1));

# Returns count of 
# required arrangements
def countUtil(p, q, r):
    
    # Three cases arise:
    # Last required balls is type P
    # Last required balls is type Q
    # Last required balls is type R
    return (countWays(p, q, r, 0) + 
            countWays(p, q, r, 1) + 
            countWays(p, q, r, 2)); 

# Driver Code
p = 1; 
q = 1;
r = 1;
print(countUtil(p, q, r));
    
# This code is contributed by mits
C#
// C# program to count number 
// of ways to arrange three types of
// balls such that no two balls of 
// same color are adjacent to each other
using System;

class GFG {
    
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p', 
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q,
                            int r, int last) 
    {
        
        // if number of balls of any 
        // color becomes less than 0 
        // the number of ways
        // arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
            return 0;
    
        // If last ball required is
        // of type P and the number
        // of balls of P type is 1
        // while number of balls of
        // other color is 0 the number
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 
                              && last == 0)
            return 1;
    
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 
                               && last == 1)
            return 1;
        if (p == 0 && q == 0 && r == 1 
                               && last == 2)
            return 1;
    
        // if last ball required is P
        // and the number of ways is
        // the sum of number of ways 
        // to form sequence with 'p-1' P
        // balls, q Q Balls and r R balls
        // ending with Q and R.
        if (last == 0)
            return countWays(p - 1, q, r, 1) +
                    countWays(p - 1, q, r, 2);
    
        // Same as above case for 'q' and 'r'
        if (last == 1)
            return countWays(p, q - 1, r, 0) +
                countWays(p, q - 1, r, 2);
        
        if (last == 2)
            return countWays(p, q, r - 1, 0) +
                    countWays(p, q, r - 1, 1);
    
        return 0;
    }
    
    // Returns count of required arrangements
    static int countUtil(int p, int q, int r)
    {
        
        // Three cases arise:
        // 1. Last required balls is type P
        // 2. Last required balls is type Q
        // 3. Last required balls is type R
        return countWays(p, q, r, 0) + 
               countWays(p, q, r, 1) + 
               countWays(p, q, r, 2); 
    }
    
    // Driver code
    public static void Main() 
    {
        int p = 1, q = 1, r = 1;
        
        Console.Write(countUtil(p, q, r));
    }
}

// This code is contributed by nitin mittal.
 
Javascript
<script>

// JavaScript program to count number
// of ways to arrange three
// types of balls such that no
// two balls of same color
// are adjacent to each other
 
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p', 
    // 1 for 'q' and 2 for 'r'
    function countWays(p, q, r, last) 
    {
    
        // if number of balls of any 
        // color becomes less than 0 
        // the number of ways arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
        return 0;
      
        // If last ball required is
        // of type P and the number
        // of balls of P type is 1
        // while number of balls of
        // other color is 0 the number
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 && last == 0)
            return 1;
      
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 && last == 1)
            return 1;
        if (p == 0 && q == 0 && r == 1 && last == 2)
            return 1;
      
        // if last ball required is P
        // and the number of ways is
        // the sum of number of ways 
        // to form sequence with 'p-1' P
        // balls, q Q Balls and r R balls
        // ending with Q and R.
        if (last == 0)
        return countWays(p - 1, q, r, 1) +
               countWays(p - 1, q, r, 2);
      
        // Same as above case for 'q' and 'r'
        if (last == 1)
            return countWays(p, q - 1, r, 0) +
                   countWays(p, q - 1, r, 2);
          
        if (last == 2)
        return countWays(p, q, r - 1, 0) +
               countWays(p, q, r - 1, 1);
      
        return 0;
    }
      
    // Returns count of required arrangements
    function countUtil(p, q, r)
    {
    
        // Three cases arise:
        return countWays(p, q, r, 0) + // Last required balls is type P
               countWays(p, q, r, 1) + // Last required balls is type Q
               countWays(p, q, r, 2);  // Last required balls is type R
    } 

// Driver Code

        let p = 1, q = 1, r = 1;
        document.write(countUtil(p, q, r));
    
    // This code is contributed by target_2.
</script>
PHP
<?php
// PHP program to count number
// of ways to arrange three
// types of balls such that 
// no two balls of same color
// are adjacent to each other

// Returns count of arrangements
// where last placed ball is
// 'last'. 'last' is 0 for 'p',
// 1 for 'q' and 2 for 'r'
function countWays($p, $q, 
                   $r, $last)
{
    
    // if number of balls of 
    // any color becomes less
    // than 0 the number of 
    // ways arrangements is 0.
    if ($p < 0 || $q 
           < 0 || $r < 0)
        return 0;

    // If last ball required is
    // of type P and the number
    // of balls of P type is 1
    // while number of balls of
    // other color is 0 the number
    // of ways is 1.
    if ($p == 1 && $q == 0 && 
        $r == 0 && $last == 0)
        return 1;

    // Same case as above 
    // for 'q' and 'r'
    if ($p == 0 && $q == 1 && 
        $r == 0 && $last == 1)
        return 1;
        
    if ($p == 0 && $q == 0 &&
        $r == 1 && $last == 2)
        return 1;

    // if last ball required is P 
    // and the number of ways is
    // the sum of number of ways 
    // to form sequence with 'p-1' P
    // balls, q Q Balls and r R 
    // balls ending with Q and R.
    if ($last == 0)
        return countWays($p - 1, $q, $r, 1) + 
               countWays($p - 1, $q, $r, 2);

    // Same as above case
    // for 'q' and 'r'
    if ($last == 1)
        return countWays($p, $q - 1, $r, 0) + 
               countWays($p, $q - 1, $r, 2);
    if ($last == 2)
        return countWays($p, $q, $r - 1, 0) + 
               countWays($p, $q, $r - 1, 1);
}

// Returns count of 
// required arrangements
function countUtil($p, $q, $r)
{
    
    // Three cases arise:
    // Last required balls is type P
    // Last required balls is type Q
    // Last required balls is type R
    return countWays($p, $q, $r, 0) + 
           countWays($p, $q, $r, 1) + 
           countWays($p, $q, $r, 2); 
}

    // Driver Code
    $p = 1; 
    $q = 1;
    $r = 1;
    echo(countUtil($p, $q, $r));
    
// This code is contributed by nitin mittal.
?>

Output
6

Time Complexity: The time complexity of this program is O(3^n), where n is the total number of balls. This is because for each ball placement, there are three possibilities (p, q, or r) and there are n balls in total. Therefore, the total number of possible arrangements is 3^n.

Auxiliary Space : The space complexity of this program is O(1) because there are no additional data structures being used beyond the input variables and the return value. The program uses recursive function calls to calculate the number of ways to arrange the balls, and these function calls use the call stack to store intermediate values. However, the depth of the call stack is at most n, so the space complexity is O(1) in terms of the input size.


We can observe that there are many subproblems being solved again and again so the problem can be solved using Dynamic Programming (DP). We can easily make memoization solution to this problem. 
 

C++
// C++ program to count number of ways to arrange three
// types of balls such that no two balls of same color
// are adjacent to each other
#include<bits/stdc++.h>
using namespace std;
#define MAX 100

// table to store to store results of subproblems
int dp[MAX][MAX][MAX][3];

// Returns count of arrangements where last placed ball is
// 'last'.  'last' is 0 for 'p', 1 for 'q' and 2 for 'r'
int countWays(int p, int q, int r, int last)
{
    // if number of balls of any color becomes less
    // than 0 the number of ways arrangements is 0.
    if (p<0 || q<0 || r<0)
        return 0;

    // If last ball required is of type P and the number
    // of balls of P type is 1 while number of balls of
    // other color is 0 the number of ways is 1.
    if (p==1 && q==0 && r==0 && last==0)
        return 1;

    // Same case as above for 'q' and 'r'
    if (p==0 && q==1 && r==0 && last==1)
        return 1;
    if (p==0 && q==0 && r==1 && last==2)
        return 1;

    // If this subproblem is already evaluated
    if (dp[p][q][r][last] != -1)
        return dp[p][q][r][last];

    // if last ball required is P and the number of ways is
    // the sum of number of ways to form sequence with 'p-1' P
    // balls, q Q Balls and r R balls ending with Q and R.
    if (last==0)
       dp[p][q][r][last] = countWays(p-1,q,r,1) + countWays(p-1,q,r,2);

    // Same as above case for 'q' and 'r'
    else if (last==1)
       dp[p][q][r][last] = countWays(p,q-1,r,0) + countWays(p,q-1,r,2);
    else //(last==2)
       dp[p][q][r][last] =  countWays(p,q,r-1,0) + countWays(p,q,r-1,1);

    return dp[p][q][r][last];
}

// Returns count of required arrangements
int countUtil(int p, int q, int r)
{
   // Initialize 'dp' array
   memset(dp, -1, sizeof(dp));

   // Three cases arise:
   return countWays(p, q, r, 0) +  // Last required balls is type P
          countWays(p, q, r, 1) +  // Last required balls is type Q
          countWays(p, q, r, 2); // Last required balls is type R
}

// Driver code to test above
int main()
{
    int p = 1, q = 1, r = 1;
    printf("%d", countUtil(p, q, r));
    return 0;
}
Java
// Java program to count number
// of ways to arrange three
// types of balls such that no
// two balls of same color
// are adjacent to each other
import java.util.Arrays;

class GFG 
{

    static final int MAX = 100;
    
    // table to store to store results of subproblems
    static int dp[][][][] = new int[MAX][MAX][MAX][3];
    
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p',
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q, int r, int last)
    {
        // if number of balls of any 
        // color becomes less than 0
        // the number of ways arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
        return 0;
    
        // If last ball required is 
        // of type P and the number
        // of balls of P type is 1 
        // while number of balls of
        // other color is 0 the number 
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 && last == 0)
            return 1;
    
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 && last == 1)
            return 1;
        
        if (p == 0 && q == 0 && r == 1 && last == 2)
            return 1;
    
        // If this subproblem is already evaluated
        if (dp[p][q][r][last] != -1)
            return dp[p][q][r][last];
    
        // if last ball required is P and 
        // the number of ways is the sum
        // of number of ways to form sequence
        // with 'p-1' P balls, q Q balss and
        // r R balls ending with Q and R.
        if (last == 0)
        dp[p][q][r][last] = countWays(p - 1, q, r, 1) + 
                            countWays(p - 1, q, r, 2);
    
        // Same as above case for 'q' and 'r'
        else if (last == 1)
        dp[p][q][r][last] = countWays(p, q - 1, r, 0) + 
                            countWays(p, q - 1, r, 2);
        //(last==2)
        else 
        dp[p][q][r][last] = countWays(p, q, r - 1, 0) + 
                            countWays(p, q, r - 1, 1);
    
        return dp[p][q][r][last];
    }
    
    // Returns count of required arrangements
    static int countUtil(int p, int q, int r)
    {
        // Initialize 'dp' array
        for (int[][][] row : dp)
        {
            for (int[][] innerRow : row) 
            {
                for (int[] innerInnerRow : innerRow)
                {
                    Arrays.fill(innerInnerRow, -1);
                }
            }
        };
    
        // Three cases arise:
        return countWays(p, q, r, 0) + // Last required balls is type P
            countWays(p, q, r, 1) +    // Last required balls is type Q
            countWays(p, q, r, 2);       // Last required balls is type R
    }

    // Driver code
    public static void main(String[] args)
    {
        int p = 1, q = 1, r = 1;
        System.out.print(countUtil(p, q, r));
    }
}

// This code is contributed by Anant Agarwal.
Python3
# Python3 program to count number of ways to 
# arrange three types of balls such that no 
# two balls of same color are adjacent to each other
MAX = 100; 

# table to store to store results of subproblems 
dp = [[[[-1] * 4 for i in range(MAX)] 
                 for j in range(MAX)] 
                 for k in range(MAX)]; 

# Returns count of arrangements where last 
# placed ball is 'last'. 'last' is 0 for 'p', 
# 1 for 'q' and 2 for 'r' 
def countWays(p, q, r, last):

    # if number of balls of any color becomes less 
    # than 0 the number of ways arrangements is 0. 
    if (p < 0 or q < 0 or r < 0): 
        return 0; 

    # If last ball required is of type P and the 
    # number of balls of P type is 1 while number 
    # of balls of other color is 0 the number of
    # ways is 1. 
    if (p == 1 and q == 0 and 
        r == 0 and last == 0): 
        return 1; 

    # Same case as above for 'q' and 'r' 
    if (p == 0 and q == 1 and
        r == 0 and last == 1): 
        return 1; 
    if (p == 0 and q == 0 and 
        r == 1 and last == 2): 
        return 1; 

    # If this subproblem is already evaluated 
    if (dp[p][q][r][last] != -1): 
        return dp[p][q][r][last]; 

    # if last ball required is P and the number 
    # of ways is the sum of number of ways to  
    # form sequence with 'p-1' P balls, q Q Balls
    # and r R balls ending with Q and R. 
    if (last == 0):
        dp[p][q][r][last] = (countWays(p - 1, q, r, 1) + 
                             countWays(p - 1, q, r, 2)); 

    # Same as above case for 'q' and 'r' 
    elif (last == 1):
        dp[p][q][r][last] = (countWays(p, q - 1, r, 0) + 
                             countWays(p, q - 1, r, 2)); 
    else:
        
        #(last==2)
        dp[p][q][r][last] = (countWays(p, q, r - 1, 0) + 
                             countWays(p, q, r - 1, 1)); 

    return dp[p][q][r][last]; 

# Returns count of required arrangements 
def countUtil(p, q, r):
    
    # Three cases arise:
    # Last required balls is type P
    # Last required balls is type Q
    # Last required balls is type R
    return (countWays(p, q, r, 0) + 
            countWays(p, q, r, 1) + 
            countWays(p, q, r, 2));

# Driver Code
p, q, r = 1, 1, 1; 
print(countUtil(p, q, r)); 

# This code is contributed by mits
C#
// C# program to count number 
// of ways to arrange three 
// types of balls such that no 
// two balls of same color 
// are adjacent to each other 
using System;

class GFG 
{ 

    static int MAX = 101; 
    
    // table to store to store results of subproblems 
    static int[,,,] dp = new int[MAX, MAX, MAX, 4]; 
    
    // Returns count of arrangements 
    // where last placed ball is 
    // 'last'. 'last' is 0 for 'p', 
    // 1 for 'q' and 2 for 'r' 
    static int countWays(int p, int q, int r, int last) 
    { 
        // if number of balls of any 
        // color becomes less than 0 
        // the number of ways arrangements is 0. 
        if (p < 0 || q < 0 || r < 0) 
        return 0; 
    
        // If last ball required is 
        // of type P and the number 
        // of balls of P type is 1 
        // while number of balls of 
        // other color is 0 the number 
        // of ways is 1. 
        if (p == 1 && q == 0 && r == 0 && last == 0) 
            return 1; 
    
        // Same case as above for 'q' and 'r' 
        if (p == 0 && q == 1 && r == 0 && last == 1) 
            return 1; 
        
        if (p == 0 && q == 0 && r == 1 && last == 2) 
            return 1; 
    
        // If this subproblem is already evaluated 
        if (dp[p, q, r, last] != -1) 
            return dp[p, q, r, last]; 
    
        // if last ball required is P and 
        // the number of ways is the sum 
        // of number of ways to form sequence 
        // with 'p-1' P balls, q Q balss and 
        // r R balls ending with Q and R. 
        if (last == 0) 
        dp[p, q, r, last] = countWays(p - 1, q, r, 1) + 
                            countWays(p - 1, q, r, 2); 
    
        // Same as above case for 'q' and 'r' 
        else if (last == 1) 
        dp[p, q, r, last] = countWays(p, q - 1, r, 0) + 
                            countWays(p, q - 1, r, 2); 
        //(last==2) 
        else
        dp[p, q, r, last] = countWays(p, q, r - 1, 0) + 
                            countWays(p, q, r - 1, 1); 
    
        return dp[p, q, r, last]; 
    } 
    
    // Returns count of required arrangements 
    static int countUtil(int p, int q, int r) 
    { 
        // Initialize 'dp' array 
        for(int i = 0; i < MAX; i++)
        for(int j = 0; j < MAX; j++)
        for(int k = 0; k < MAX; k++)
        for(int l = 0; l < 4; l++)
        dp[i, j, k, l] = -1;
    
        // Three cases arise: 
        return countWays(p, q, r, 0) + // Last required balls is type P 
            countWays(p, q, r, 1) + // Last required balls is type Q 
            countWays(p, q, r, 2); // Last required balls is type R 
    } 

    // Driver code 
    static void Main() 
    { 
        int p = 1, q = 1, r = 1; 
        Console.WriteLine(countUtil(p, q, r)); 
    } 
} 

// This code is contributed by mits. 
Javascript
<script>

// javascript program to count number
// of ways to arrange three
// types of balls such that no
// two balls of same color
// are adjacent to each other


var MAX = 100;

// table to store to store results of subproblems
var dp = Array(MAX).fill(-1).map(x => 
Array(MAX).fill(-1).map(x =>
Array(MAX).fill(-1).map(x => Array(3).fill(-1))));

// Returns count of arrangements
// where last placed ball is
// 'last'. 'last' is 0 for 'p',
// 1 for 'q' and 2 for 'r'
function countWays( p , q , r , last)
{
    // if number of balls of any 
    // color becomes less than 0
    // the number of ways arrangements is 0.
    if (p < 0 || q < 0 || r < 0)
    return 0;

    // If last ball required is 
    // of type P and the number
    // of balls of P type is 1 
    // while number of balls of
    // other color is 0 the number 
    // of ways is 1.
    if (p == 1 && q == 0 && r == 0 && last == 0)
        return 1;

    // Same case as above for 'q' and 'r'
    if (p == 0 && q == 1 && r == 0 && last == 1)
        return 1;
    
    if (p == 0 && q == 0 && r == 1 && last == 2)
        return 1;

    // If this subproblem is already evaluated
    if (dp[p][q][r][last] != -1)
        return dp[p][q][r][last];

    // if last ball required is P and 
    // the number of ways is the sum
    // of number of ways to form sequence
    // with 'p-1' P balls, q Q balss and
    // r R balls ending with Q and R.
    if (last == 0)
    dp[p][q][r][last] = countWays(p - 1, q, r, 1) + 
                        countWays(p - 1, q, r, 2);

    // Same as above case for 'q' and 'r'
    else if (last == 1)
    dp[p][q][r][last] = countWays(p, q - 1, r, 0) + 
                        countWays(p, q - 1, r, 2);
    //(last==2)
    else 
    dp[p][q][r][last] = countWays(p, q, r - 1, 0) + 
                        countWays(p, q, r - 1, 1);

    return dp[p][q][r][last];
}

// Returns count of required arrangements
function countUtil(p , q , r)
{

    // Three cases arise:
    return countWays(p, q, r, 0) + // Last required balls is type P
        countWays(p, q, r, 1) +    // Last required balls is type Q
        countWays(p, q, r, 2);       // Last required balls is type R
}

// Driver code
var p = 1, q = 1, r = 1;
document.write(countUtil(p, q, r));

// This code contributed by Princi Singh 
</script>
PHP
<?php
// PHP program to count number of ways to 
// arrange three types of balls such that 
// no two balls of same color are adjacent
// to each other
$MAX = 100; 

// table to store to store results of subproblems 
$dp = array_fill(0, $MAX, array_fill(0, $MAX, 
      array_fill(0, $MAX, array_fill(0, 3, -1)))); 

// Returns count of arrangements where last 
// placed ball is 'last'. 'last' is 0 for 'p', 
// 1 for 'q' and 2 for 'r' 
function countWays($p, $q, $r, $last) 
{
    global $dp;
    
    // if number of balls of any color becomes less 
    // than 0 the number of ways arrangements is 0. 
    if ($p < 0 || $q < 0 || $r < 0) 
        return 0; 

    // If last ball required is of type P and the
    // number of balls of P type is 1 while number 
    // of balls of other color is 0 the number of 
    // ways is 1. 
    if ($p == 1 && $q == 0 && $r == 0 && $last == 0) 
        return 1; 

    // Same case as above for 'q' and 'r' 
    if ($p == 0 && $q == 1 && $r == 0 && $last == 1) 
        return 1; 
    if ($p == 0 && $q == 0 && $r == 1 && $last == 2) 
        return 1; 

    // If this subproblem is already evaluated 
    if ($dp[$p][$q][$r][$last] != -1) 
        return $dp[$p][$q][$r][$last]; 

    // if last ball required is P and the number of
    // ways is the sum of number of ways to form 
    // sequence with 'p-1' P balls, q Q Balls and r 
    // R balls ending with Q and R. 
    if ($last == 0) 
    $dp[$p][$q][$r][$last] = countWays($p - 1, $q, $r, 1) + 
                             countWays($p - 1, $q, $r, 2); 

    // Same as above case for 'q' and 'r' 
    else if ($last == 1) 
    $dp[$p][$q][$r][$last] = countWays($p, $q - 1, $r, 0) + 
                             countWays($p, $q - 1, $r, 2); 
    else //(last==2) 
    $dp[$p][$q][$r][$last] = countWays($p, $q, $r - 1, 0) + 
                             countWays($p, $q, $r - 1, 1); 

    return $dp[$p][$q][$r][$last]; 
} 

// Returns count of required arrangements 
function countUtil($p, $q, $r) 
{ 

// Three cases arise: 
return countWays($p, $q, $r, 0) + // Last required balls is type P 
       countWays($p, $q, $r, 1) + // Last required balls is type Q 
       countWays($p, $q, $r, 2); // Last required balls is type R 
} 

// Driver code
$p = 1;
$q = 1;
$r = 1; 
print(countUtil($p, $q, $r)); 

// This code is contributed by mits
?>

Output
6


Time complexity : O(p*q*r) 
Auxiliary Space : O(p*q*r*3)


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 :

  • Initialize a 3D array dp with zeros.
  • Set the base cases for p, q, and r.
  • Iterate through all possible combinations of p, q, and r.
  • Skip the base cases.
  • Update the DP values based on the previous states.
  • Return the final count stored in dp[p][q][r].

Implementation :

C++
#include <bits/stdc++.h>
using namespace std;
#define MAX 100

// Function to count the number of arrangements
int countUtil(int p, int q, int r)
{
    int dp[MAX][MAX][MAX];
    memset(dp, 0, sizeof(dp));  // Initializing the DP table with zeros

    // Base cases
    dp[1][0][0] = 1;  // If only one 'p' is present
    dp[0][1][0] = 1;  // If only one 'q' is present
    dp[0][0][1] = 1;  // If only one 'r' is present

    // Fill the DP table
    for (int i = 0; i <= p; i++)
    {
        for (int j = 0; j <= q; j++)
        {
            for (int k = 0; k <= r; k++)
            {
                // Skip the base cases as they are already initialized
                if (i == 1 && j == 0 && k == 0)
                    continue;
                if (i == 0 && j == 1 && k == 0)
                    continue;
                if (i == 0 && j == 0 && k == 1)
                    continue;

                // Update DP values based on previous states
                if (i - 1 >= 0)
                    dp[i][j][k] += dp[i - 1][j][k];  // Add the count when using 'p'
                if (j - 1 >= 0)
                    dp[i][j][k] += dp[i][j - 1][k];  // Add the count when using 'q'
                if (k - 1 >= 0)
                    dp[i][j][k] += dp[i][j][k - 1];  // Add the count when using 'r'
            }
        }
    }

    return dp[p][q][r];  // Return the count of required arrangements
}

// Driver code to test above function
int main()
{
    int p = 1, q = 1, r = 1;
    printf("%d", countUtil(p, q, r));
    return 0;
}

// -- by bhardwajji
Java
// Java code

import java.util.Arrays;

public class Main {
    final static int MAX = 100;

    // Function to count the number of arrangements
    static int countUtil(int p, int q, int r) {
        int[][][] dp = new int[MAX][MAX][MAX];
        for (int[][] d1 : dp) {
            for (int[] d2 : d1) {
                Arrays.fill(d2, 0); // Initializing the DP table with zeros
            }
        }
      // Base cases
    dp[1][0][0] = 1;  // If only one 'p' is present
    dp[0][1][0] = 1;  // If only one 'q' is present
    dp[0][0][1] = 1;  // If only one 'r' is present
 
    // Fill the DP table
    for (int i = 0; i <= p; i++)
    {
        for (int j = 0; j <= q; j++)
        {
            for (int k = 0; k <= r; k++)
            {
                // Skip the base cases as they are already initialized
                if (i == 1 && j == 0 && k == 0)
                    continue;
                if (i == 0 && j == 1 && k == 0)
                    continue;
                if (i == 0 && j == 0 && k == 1)
                    continue;
 
                // Update DP values based on previous states
                if (i - 1 >= 0)
                    dp[i][j][k] += dp[i - 1][j][k];  // Add the count when using 'p'
                if (j - 1 >= 0)
                    dp[i][j][k] += dp[i][j - 1][k];  // Add the count when using 'q'
                if (k - 1 >= 0)
                    dp[i][j][k] += dp[i][j][k - 1];  // Add the count when using 'r'
            }
        }
    }
 
    return dp[p][q][r];  // Return the count of required arrangements
    }
    
// Driver code to test above function
    public static void main(String[] args) {
        int p = 1, q = 1, r = 1;
        System.out.println(countUtil(p, q, r));
    }
}

// This code is contributed by Pushpesh Raj
Python3
# Function to count the number of arrangements
def count_util(p, q, r):
    MAX = 100
    dp = [[[0 for _ in range(MAX)] for _ in range(MAX)] for _ in range(MAX)]

    # Base cases
    dp[1][0][0] = 1  # If only one 'p' is present
    dp[0][1][0] = 1  # If only one 'q' is present
    dp[0][0][1] = 1  # If only one 'r' is present

    # Fill the DP table
    for i in range(p + 1):
        for j in range(q + 1):
            for k in range(r + 1):
                # Skip the base cases as they are already initialized
                if i == 1 and j == 0 and k == 0:
                    continue
                if i == 0 and j == 1 and k == 0:
                    continue
                if i == 0 and j == 0 and k == 1:
                    continue

                # Update DP values based on previous states
                if i - 1 >= 0:
                    dp[i][j][k] += dp[i - 1][j][k]  # Add the count when using 'p'
                if j - 1 >= 0:
                    dp[i][j][k] += dp[i][j - 1][k]  # Add the count when using 'q'
                if k - 1 >= 0:
                    dp[i][j][k] += dp[i][j][k - 1]  # Add the count when using 'r'

    return dp[p][q][r]  # Return the count of required arrangements


# Driver code to test the above function
if __name__ == "__main__":
    p, q, r = 1, 1, 1
    print(count_util(p, q, r))
C#
using System;

class Program
{
    static int MAX = 100;

    // Function to count the number of arrangements
    static int CountUtil(int p, int q, int r)
    {
        int[,,] dp = new int[MAX, MAX, MAX];
        Array.Clear(dp, 0, dp.Length);  // Initializing the DP table with zeros

        // Base cases
        dp[1, 0, 0] = 1;  // If only one 'p' is present
        dp[0, 1, 0] = 1;  // If only one 'q' is present
        dp[0, 0, 1] = 1;  // If only one 'r' is present

        // Fill the DP table
        for (int i = 0; i <= p; i++)
        {
            for (int j = 0; j <= q; j++)
            {
                for (int k = 0; k <= r; k++)
                {
                    // Skip the base cases as they are already initialized
                    if (i == 1 && j == 0 && k == 0)
                        continue;
                    if (i == 0 && j == 1 && k == 0)
                        continue;
                    if (i == 0 && j == 0 && k == 1)
                        continue;

                    // Update DP values based on previous states
                    if (i - 1 >= 0)
                        dp[i, j, k] += dp[i - 1, j, k];  // Add the count when using 'p'
                    if (j - 1 >= 0)
                        dp[i, j, k] += dp[i, j - 1, k];  // Add the count when using 'q'
                    if (k - 1 >= 0)
                        dp[i, j, k] += dp[i, j, k - 1];  // Add the count when using 'r'
                }
            }
        }

        return dp[p, q, r];  // Return the count of required arrangements
    }

    // Driver code to test above function
    static void Main()
    {
        int p = 1, q = 1, r = 1;
        Console.WriteLine(CountUtil(p, q, r));
    }
}
Javascript
// Function to count the number of arrangements
function countUtil(p, q, r) {
    const MAX = 100;
    const dp = new Array(MAX).fill(null).map(() => new Array(MAX).fill(null).map(() => new Array(MAX).fill(0)));

    // Initializing the DP table with zeros
    for (let i = 0; i < MAX; i++) {
        for (let j = 0; j < MAX; j++) {
            for (let k = 0; k < MAX; k++) {
                dp[i][j][k] = 0;
            }
        }
    }

    // Base cases
    dp[1][0][0] = 1; // If only one 'p' is present
    dp[0][1][0] = 1; // If only one 'q' is present
    dp[0][0][1] = 1; // If only one 'r' is present

    // Fill the DP table
    for (let i = 0; i <= p; i++) {
        for (let j = 0; j <= q; j++) {
            for (let k = 0; k <= r; k++) {
                // Skip the base cases as they are already initialized
                if (i === 1 && j === 0 && k === 0) {
                    continue;
                }
                if (i === 0 && j === 1 && k === 0) {
                    continue;
                }
                if (i === 0 && j === 0 && k === 1) {
                    continue;
                }

                // Update DP values based on previous states
                if (i - 1 >= 0) {
                    dp[i][j][k] += dp[i - 1][j][k]; // Add the count when using 'p'
                }
                if (j - 1 >= 0) {
                    dp[i][j][k] += dp[i][j - 1][k]; // Add the count when using 'q'
                }
                if (k - 1 >= 0) {
                    dp[i][j][k] += dp[i][j][k - 1]; // Add the count when using 'r'
                }
            }
        }
    }

    return dp[p][q][r]; // Return the count of required arrangements
}

// Driver code to test the function
function main() {
    const p = 1, q = 1, r = 1;
    console.log(countUtil(p, q, r));
}

main();

Output
6


Time complexity : O(p*q*r) 
Auxiliary Space : O(p*q*r)


This article is contributed by Bhavuk Chawla.
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads