Given N blocks, out of which K is colored. These K-colored blocks are denoted by an array arr[]. The task is to count the number of ways to color the remaining uncolored blocks such that only any one of the adjacent blocks, of a colored block, can be colored in one step. Print the answer with modulo 109+7.
Examples:
Input: N = 6, K = 3, arr[] = {1, 2, 6}Â
Output: 4Â
Explanation:Â
The following are the 4 ways to color the blocks(each set represents the order in which blocks are colored):Â
1. {3, 4, 5}Â
2. {3, 5, 4}Â
3. {5, 3, 4}Â
4. {5, 4, 3}Input: N = 9, K = 3, A = [3, 6, 7]Â
Output: 180Â
Naive Approach: The idea is to use recursion. Below are the steps:Â
- Traverse each block from 1 to N.
- If the current block(say b) is not colored, then check whether one of the adjacent blocks is colored or not.
- If the adjacent block is colored, then color the current block and recursively iterate to find the next uncolored block.
- After the above recursive call ends, then, uncolored the block for the blockquotevious recursive call and repeat the above steps for the next uncolored block.
- The count of coloring the blocks in all the above recursive calls gives the number of ways to color the uncolored block.
Below is the implementation of the above approach:Â
C++
// C++ program for the above approach Â
#include <bits/stdc++.h> using namespace std; Â
const int mod = 1000000007; Â
// Recursive function to count the ways int countWays( int colored[], int count, Â Â Â Â Â Â Â Â Â Â Â Â Â Â int n) { Â
    // Base case     if (count == n) {         return 1;     } Â
    // Initialise answer to 0     int answer = 0; Â
    // Color each uncolored block according     // to the given condition     for ( int i = 1; i < n + 1; i++) { Â
        // If any block is uncolored         if (colored[i] == 0) { Â
            // Check if adjacent blocks             // are colored or not             if (colored[i - 1] == 1                 || colored[i + 1] == 1) { Â
                // Color the block                 colored[i] = 1; Â
                // recursively iterate for                 // next uncolored block                 answer = (answer                           + countWays(colored,                                       count + 1,                                       n))                          % mod; Â
                // Uncolored for the next                 // recursive call                 colored[i] = 0;             }         }     } Â
    // Return the final count     return answer; } Â
// Function to count the ways to color // block int waysToColor( int arr[], int n, int k) { Â
    // Mark which blocks are colored in     // each recursive step     int colored[n + 2] = { 0 }; Â
    for ( int i = 0; i < k; i++) {         colored[arr[i]] = 1;     } Â
    // Function call to count the ways     return countWays(colored, k, n); } Â
// Driver Code int main() {     // Number of blocks     int N = 6; Â
    // Number of colored blocks     int K = 3;     int arr[K] = { 1, 2, 6 }; Â
    // Function call     cout << waysToColor(arr, N, K);     return 0; } |
Java
// Java program for the above approach import java.util.*; class GFG{ Â
static int mod = 1000000007 ; Â
// Recursive function to count the ways static int countWays( int colored[], Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int count, int n) { Â
    // Base case     if (count == n)     {         return 1 ;     } Â
    // Initialise answer to 0     int answer = 0 ; Â
    // Color each uncolored block according     // to the given condition     for ( int i = 1 ; i < n + 1 ; i++)     { Â
        // If any block is uncolored         if (colored[i] == 0 )         { Â
            // Check if adjacent blocks             // are colored or not             if (colored[i - 1 ] == 1 ||                 colored[i + 1 ] == 1 )             { Â
                // Color the block                 colored[i] = 1 ; Â
                // recursively iterate for                 // next uncolored block                 answer = (answer +                           countWays(colored,                                     count + 1 ,                                     n)) % mod; Â
                // Uncolored for the next                 // recursive call                 colored[i] = 0 ;             }         }     } Â
    // Return the final count     return answer; } Â
// Function to count the ways to color // block static int waysToColor( int arr[], Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int n, int k) { Â
    // Mark which blocks are colored in     // each recursive step     int colored[] = new int [n + 2 ]; Â
    for ( int i = 0 ; i < k; i++)     {         colored[arr[i]] = 1 ;     } Â
    // Function call to count the ways     return countWays(colored, k, n); } Â
// Driver Code public static void main(String[] args) {     // Number of blocks     int N = 6 ; Â
    // Number of colored blocks     int K = 3 ;     int arr[] = { 1 , 2 , 6 }; Â
    // Function call     System.out.print(waysToColor(arr, N, K)); } } Â
// This code is contributed by sapnasingh4991 |
Python3
# Python3 program for the above approach mod = 1000000007 Â
# Recursive function to count the ways def countWays(colored, count, n): Â
    # Base case     if (count = = n):         return 1 Â
    # Initialise answer to 0     answer = 0 Â
    # Color each uncolored block according     # to the given condition     for i in range ( 1 , n + 1 ): Â
        # If any block is uncolored         if (colored[i] = = 0 ): Â
            # Check if adjacent blocks             # are colored or not             if (colored[i - 1 ] = = 1 or                 colored[i + 1 ] = = 1 ): Â
                # Color the block                 colored[i] = 1 Â
                # recursively iterate for                 # next uncolored block                 answer = ((answer +                            countWays(colored,                                      count + 1 ,                                        n)) % mod) Â
                # Uncolored for the next                 # recursive call                 colored[i] = 0 Â
    # Return the final count     return answer Â
# Function to count the ways to color # block def waysToColor( arr, n, k): Â
    # Mark which blocks are colored in     # each recursive step     colored = [ 0 ] * (n + 2 )          for i in range (k):         colored[arr[i]] = 1 Â
    # Function call to count the ways     return countWays(colored, k, n) Â
# Driver Code if __name__ = = "__main__" :          # Number of blocks     N = 6 Â
    # Number of colored blocks     K = 3     arr = [ 1 , 2 , 6 ] Â
    # Function call     print (waysToColor(arr, N, K)) Â
# This code is contributed by chitranayal |
C#
// C# program for the above approach using System; class GFG{ Â
static int mod = 1000000007; Â
// Recursive function to count the ways static int countWays( int []colored, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int count, int n) { Â
    // Base case     if (count == n)     {         return 1;     } Â
    // Initialise answer to 0     int answer = 0; Â
    // Color each uncolored block according     // to the given condition     for ( int i = 1; i < n + 1; i++)     { Â
        // If any block is uncolored         if (colored[i] == 0)         { Â
            // Check if adjacent blocks             // are colored or not             if (colored[i - 1] == 1 ||                 colored[i + 1] == 1)             { Â
                // Color the block                 colored[i] = 1; Â
                // recursively iterate for                 // next uncolored block                 answer = (answer +                           countWays(colored,                                     count + 1,                                     n)) % mod; Â
                // Uncolored for the next                 // recursive call                 colored[i] = 0;             }         }     } Â
    // Return the final count     return answer; } Â
// Function to count the ways to color // block static int waysToColor( int []arr, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int n, int k) { Â
    // Mark which blocks are colored in     // each recursive step     int []colored = new int [n + 2]; Â
    for ( int i = 0; i < k; i++)     {         colored[arr[i]] = 1;     } Â
    // Function call to count the ways     return countWays(colored, k, n); } Â
// Driver Code public static void Main() {     // Number of blocks     int N = 6; Â
    // Number of colored blocks     int K = 3;     int []arr = { 1, 2, 6 }; Â
    // Function call     Console.Write(waysToColor(arr, N, K)); } } Â
// This code is contributed by Code_Mech |
Javascript
<script> Â
// Javascript program for the above approach Â
let mod = 1000000007;   // Recursive function to count the ways function countWays(colored,                      count, n) {       // Base case     if (count == n)     {         return 1;     }       // Let initialise answer to 0     let answer = 0;       // Color each uncolored block according     // to the given condition     for (let i = 1; i < n + 1; i++)     {           // If any block is uncolored         if (colored[i] == 0)         {               // Check if adjacent blocks             // are colored or not             if (colored[i - 1] == 1 ||                 colored[i + 1] == 1)             {                   // Color the block                 colored[i] = 1;                   // recursively iterate for                 // next uncolored block                 answer = (answer +                           countWays(colored,                                     count + 1,                                     n)) % mod;                   // Uncolored for the next                 // recursive call                 colored[i] = 0;             }         }     }       // Return the final count     return answer; }   // Function to count the ways to color // block function waysToColor(arr, n, k) {       // Mark which blocks are colored in     // each recursive step     let colored = Array.from({length: n+2}, (_, i) => 0);       for (let i = 0; i < k; i++)     {         colored[arr[i]] = 1;     }       // Function call to count the ways     return countWays(colored, k, n); } Â
// Driver Code          // Number of blocks     let N = 6;       // Number of colored blocks     let K = 3;     let arr = [ 1, 2, 6 ];       // Function call     document.write(waysToColor(arr, N, K));          </script> |
4
Â
Time Complexity: O(NN-K)Â
Auxiliary Space: O(N)
Efficient Approach: For solving this problem efficiently we will use the concept of Permutation and Combination. Below are the steps:Â
1. If the number of blocks between two consecutive colored blocks is x, then the number of ways to color these set of blocks is given by:Â
ways = 2x-1Â Â
2. Coloring each set of uncolored blocks is independent of the other. Suppose there are x blocks in one section and y blocks in the other section. To find the total combination when the two sections are merged is given by:
total combinations =Â
Â
3. Sort the colored block indices to find the length of each uncolored block section and iterate and find the combination of each two-section using the above formula.
4. Find the Binomial Coefficient using the approach discussed in this article.
Below is the implementation of the above approach:Â
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; Â
const int mod = 1000000007; Â
// Function to count the ways to color // block int waysToColor( int arr[], int n, int k) { Â Â Â Â // For storing powers of 2 Â Â Â Â int powOf2[500] = { 0 }; Â
    // For storing binomial coefficient     // values     int c[500][500]; Â
    // Calculating binomial coefficient     // using DP     for ( int i = 0; i <= n; i++) { Â
        c[i][0] = 1;         for ( int j = 1; j <= i; j++) {             c[i][j] = (c[i - 1][j]                        + c[i - 1][j - 1])                       % mod;         }     } Â
    powOf2[0] = powOf2[1] = 1; Â
    // Calculating powers of 2     for ( int i = 2; i <= n; i++) { Â
        powOf2[i] = powOf2[i - 1] * 2 % mod;     } Â
    int rem = n - k;     arr[k++] = n + 1; Â
    // Sort the indices to calculate     // length of each section     sort(arr, arr + k); Â
    // Initialise answer to 1     int answer = 1; Â
    for ( int i = 0; i < k; i++) { Â
        // Find the length of each section         int x = arr[i] - (i - 1 >= 0                               ? arr[i - 1]                               : 0)                 - 1; Â
        // Merge this section         answer *= c[rem][x] % mod * (i != 0                                              && i != k - 1                                          ? powOf2[x]                                          : 1)                   % mod;         rem -= x;     } Â
    // Return the final count     return answer; } Â
// Driver Code int main() {     // Number of blocks     int N = 6; Â
    // Number of colored blocks     int K = 3;     int arr[K] = { 1, 2, 6 }; Â
    // Function call     cout << waysToColor(arr, N, K);     return 0; } |
Java
// Java program for the above approach import java.util.*; Â
class GFG{ Â
static int mod = 1000000007 ; Â
// Function to count the ways to color // block static int waysToColor( int arr[], int n, int k) { Â Â Â Â Â Â Â Â Â // For storing powers of 2 Â Â Â Â int powOf2[] = new int [ 500 ]; Â
    // For storing binomial coefficient     // values     int [][]c = new int [ 500 ][ 500 ]; Â
    // Calculating binomial coefficient     // using DP     for ( int i = 0 ; i <= n; i++)     {        c[i][ 0 ] = 1 ;        for ( int j = 1 ; j <= i; j++)        {           c[i][j] = (c[i - 1 ][j] +                      c[i - 1 ][j - 1 ]) % mod;        }     } Â
    powOf2[ 0 ] = powOf2[ 1 ] = 1 ; Â
    // Calculating powers of 2     for ( int i = 2 ; i <= n; i++)     {        powOf2[i] = powOf2[i - 1 ] * 2 % mod;     } Â
    int rem = n - k;     arr[k++] = n + 1 ;          // Sort the indices to calculate     // length of each section     Arrays.sort(arr); Â
    // Initialise answer to 1     int answer = 1 ; Â
    for ( int i = 0 ; i < k; i++)     {                 // Find the length of each section        int x = arr[i] - (i - 1 >= 0 ?                      arr[i - 1 ] : 0 ) - 1 ;                // Merge this section        answer *= c[rem][x] % mod * (i != 0 &&                                     i != k - 1 ?                                     powOf2[x] : 1 ) %                                     mod;        rem -= x;     }          // Return the final count     return answer; } Â
// Driver Code public static void main(String[] args) {          // Number of blocks     int N = 6 ; Â
    // Number of colored blocks     int K = 3 ;     int arr[] = { 1 , 2 , 6 , 0 }; Â
    // Function call     System.out.print(waysToColor(arr, N, K)); } } Â
// This code is contributed by 29AjayKumar |
Python3
# Python3 program for the above approach mod = 1000000007 Â Â # Function to count the ways to color # block def waysToColor(arr, n, k): Â Â Â Â Â Â Â Â Â global mod Â
    # For storing powers of 2     powOf2 = [ 0 for i in range ( 500 )]       # For storing binomial coefficient     # values     c = [[ 0 for i in range ( 500 )] for j in range ( 500 )]       # Calculating binomial coefficient     # using DP     for i in range (n + 1 ):           c[i][ 0 ] = 1 ;                  for j in range ( 1 , i + 1 ):                      c[i][j] = (c[i - 1 ][j] + c[i - 1 ][j - 1 ]) % mod;       powOf2[ 0 ] = 1     powOf2[ 1 ] = 1 ;       # Calculating powers of 2     for i in range ( 2 , n + 1 ):           powOf2[i] = (powOf2[i - 1 ] * 2 ) % mod;          rem = n - k;     arr[k] = n + 1 ;     k + = 1       # Sort the indices to calculate     # length of each section     arr.sort()       # Initialise answer to 1     answer = 1 ;          for i in range (k):                  x = 0                  # Find the length of each section         if i - 1 > = 0 :             x = arr[i] - arr[i - 1 ] - 1         else :             x = arr[i] - 1           # Merge this section         answer = answer * (c[rem][x] % mod) * ((powOf2[x] if (i ! = 0 and i ! = k - 1 ) else 1 )) % mod         rem - = x;       # Return the final count     return answer; Â
# Driver Code if __name__ = = '__main__' :       # Number of blocks     N = 6 ;       # Number of colored blocks     K = 3 ;     arr = [ 1 , 2 , 6 , 0 ]       # Function call     print (waysToColor(arr, N, K)) Â
# This code is contributed by rutvik_56 |
C#
// C# program for the above approach using System; class GFG{ Â
static int mod = 1000000007; Â
// Function to count the ways to color // block static int waysToColor( int []arr, int n, int k) { Â Â Â Â Â Â Â Â Â // For storing powers of 2 Â Â Â Â int []powOf2 = new int [500]; Â
    // For storing binomial coefficient     // values     int [,]c = new int [500, 500]; Â
    // Calculating binomial coefficient     // using DP     for ( int i = 0; i <= n; i++)     {         c[i, 0] = 1;         for ( int j = 1; j <= i; j++)         {             c[i, j] = (c[i - 1, j] +                        c[i - 1, j - 1]) % mod;         }     } Â
    powOf2[0] = powOf2[1] = 1; Â
    // Calculating powers of 2     for ( int i = 2; i <= n; i++)     {         powOf2[i] = powOf2[i - 1] * 2 % mod;     } Â
    int rem = n - k;     arr[k++] = n + 1;          // Sort the indices to calculate     // length of each section     Array.Sort(arr); Â
    // Initialise answer to 1     int answer = 1; Â
    for ( int i = 0; i < k; i++)     {                  // Find the length of each section         int x = arr[i] - (i - 1 >= 0 ?                 arr[i - 1] : 0) - 1;                      // Merge this section         answer *= c[rem, x] % mod * (i != 0 &&                                      i != k - 1 ?                                      powOf2[x] : 1) %                                      mod;         rem -= x;     }          // Return the readonly count     return answer; } Â
// Driver Code public static void Main(String[] args) {          // Number of blocks     int N = 6; Â
    // Number of colored blocks     int K = 3;     int []arr = { 1, 2, 6, 0 }; Â
    // Function call     Console.Write(waysToColor(arr, N, K)); } } Â
// This code is contributed by 29AjayKumar |
Javascript
<script> Â
// JavaScript program for the above approach Â
let mod = 1000000007; Â
// Function to count the ways to color // block function waysToColor(arr,n,k) {     // For storing powers of 2     let powOf2 = new Array(500);       // For storing binomial coefficient     // values     let c = new Array(500);     for (let i=0;i<500;i++)     {         c[i]= new Array(500);         for (let j=0;j<500;j++)         {             c[i][j]=0;         }     }       // Calculating binomial coefficient     // using DP     for (let i = 0; i <= n; i++)     {        c[i][0] = 1;        for (let j = 1; j <= i; j++)        {           c[i][j] = (c[i - 1][j] +                      c[i - 1][j - 1]) % mod;        }     }       powOf2[0] = powOf2[1] = 1;       // Calculating powers of 2     for (let i = 2; i <= n; i++)     {        powOf2[i] = powOf2[i - 1] * 2 % mod;     }       let rem = n - k;     arr[k++] = n + 1;           // Sort the indices to calculate     // length of each section     arr.sort( function (a,b){ return a-b;});       // Initialise answer to 1     let answer = 1;       for (let i = 0; i < k; i++)     {                  // Find the length of each section        let x = arr[i] - (i - 1 >= 0 ?                      arr[i - 1] : 0) - 1;                 // Merge this section        answer *= c[rem][x] % mod * (i != 0 &&                                     i != k - 1 ?                                     powOf2[x] : 1) %                                     mod;        rem -= x;     }           // Return the final count     return answer; } Â
// Driver Code // Number of blocks let N = 6; Â
// Number of colored blocks let K = 3; let arr=[ 1, 2, 6 ,0]; Â
// Function call document.write(waysToColor(arr, N, K)); Â
// This code is contributed by avanitrachhadiya2155 Â
</script> |
4
Â
Time Complexity: O(N2)Â
Auxiliary Space: O(52 * 104)
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!