Ways to place K bishops on an N×N chessboard so that no two attack

Given two integers N and K, the task is to find the number of ways to place K bishops on an N × N chessboard so that no two bishops attack each other.

Here is an example for a 5×5 chessboard.

Examples:



Input: N = 2, K = 2
Output: 4
The different ways to place 2 bishops in a 2 * 2 chessboard are :

Input: N = 4, K = 3
Output: 232

Approach: This problem can be solved using dynamic programming.

  • Let dp[i][j] denote the number of ways to place j bishops on diagonals with indices up to i which have the same color as diagonal i. Then i = 1…2N-1 and j = 0…K.
  • We can calculate dp[i][j] using only values of dp[i-2] (we subtract 2 because we only consider diagonals of the same color as i). There are two ways to get dp[i][j]. Either we place all j bishops on previous diagonals: then there are dp[i-2][j] ways to achieve this. Or we place one bishop on diagonal i and j-1 bishops on previous diagonals. The number of ways to do this equals the number of squares in diagonal i – (j – 1), because each of j-1 bishops placed on previous diagonals will block one square on the current diagonal.
  • The base case is simple: dp[i][0] = 1, dp[1][1] = 1.
  • Once we have calculated all values of dp[i][j], the answer can be obtained as follows: consider all possible numbers of bishops placed on black diagonals i=0…K, with corresponding numbers of bishops on white diagonals K-i. The bishops placed on black and white diagonals never attack each other, so the placements can be done independently. The index of the last black diagonal is 2N-1, the last white one is 2N-2. For each i we add dp[2N-1][i] * dp[2N-2][K-i] to the answer.

Below is the implementation of the above approach:

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
  
class GFG {
  
    // returns the number of squares in diagonal i
    static int squares(int i)
    {
        if ((i & 1) == 1)
            return i / 4 * 2 + 1;
        else
            return (i - 1) / 4 * 2 + 2;
    }
  
    // returns the number of ways to fill a
    // n * n chessboard with k bishops so
    // that no two bishops attack each other.
    static long bishop_placements(int n, int k)
    {
        // return 0 if the number of valid places to be
        // filled is less than the number of bishops
        if (k > 2 * n - 1)
            return 0;
  
        // dp table to store the values
        long[][] dp = new long[n * 2][k + 1];
  
        // Setting the base conditions
        for (int i = 0; i < n * 2; i++)
            dp[i][0] = 1;
        dp[1][1] = 1;
  
        // calculate the required number of ways
        for (int i = 2; i < n * 2; i++) {
            for (int j = 1; j <= k; j++)
                dp[i][j] 
                    = dp[i - 2][j] 
                        + dp[i - 2][j - 1] * (squares(i) - j + 1);
        }
  
        // stores the answer
        long ans = 0;
        for (int i = 0; i <= k; i++) {
            ans += dp[n * 2 - 1][i] * dp[n * 2 - 2][k - i];
        }
  
        return ans;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int n = 2;
        int k = 2;
        long ans = bishop_placements(n, k);
        System.out.println(ans);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 implementation of the approach
  
# returns the number of squares in 
# diagonal i
def squares(i):
    if ((i & 1) == 1):
        return int(i / 4) * 2 + 1
    else:
        return int((i - 1) / 4) * 2 + 2
  
# returns the number of ways to fill a
# n * n chessboard with k bishops so
# that no two bishops attack each other.
def bishop_placements(n, k):
      
    # return 0 if the number of valid places 
    # to be filled is less than the number 
    # of bishops
    if (k > 2 * n - 1):
        return 0
  
    # dp table to store the values
    dp = [[0 for i in range(k + 1)] 
             for i in range(n * 2)]
  
    # Setting the base conditions
    for i in range(n * 2):
        dp[i][0] = 1
          
    dp[1][1] = 1
  
    # calculate the required number of ways
    for i in range(2, n * 2, 1):
        for j in range(1, k + 1, 1):
            dp[i][j] = (dp[i - 2][j] + 
                        dp[i - 2][j - 1] *
                       (squares(i) - j + 1))
  
    # stores the answer
    ans = 0
    for i in range(0, k + 1, 1):
        ans += (dp[n * 2 - 1][i] * 
                dp[n * 2 - 2][k - i])
  
    return ans
  
# Driver code
if __name__ == '__main__':
    n = 2
    k = 2
    ans = bishop_placements(n, k)
    print(ans)
  
# This code is contributed by
# Sanjit_Prasad

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach 
using System;
  
class GFG
{
  
// returns the number of squares 
// in diagonal i 
static int squares(int i) 
    if ((i & 1) == 1) 
        return i / 4 * 2 + 1; 
    else
        return (i - 1) / 4 * 2 + 2; 
  
// returns the number of ways to fill a 
// n * n chessboard with k bishops so 
// that no two bishops attack each other. 
static long bishop_placements(int n, int k) 
    // return 0 if the number of valid 
    // places to be filled is less than
    // the number of bishops 
    if (k > 2 * n - 1) 
        return 0; 
  
    // dp table to store the values 
    long[,] dp = new long[n * 2, k + 1]; 
  
    // Setting the base conditions 
    for (int i = 0; i < n * 2; i++) 
        dp[i, 0] = 1; 
    dp[1, 1] = 1; 
  
    // calculate the required
    // number of ways 
    for (int i = 2; i < n * 2; i++) 
    
        for (int j = 1; j <= k; j++) 
            dp[i, j] = dp[i - 2, j] + 
                       dp[i - 2, j - 1] * 
                        (squares(i) - j + 1); 
    
  
    // stores the answer 
    long ans = 0; 
    for (int i = 0; i <= k; i++) 
    
        ans += dp[n * 2 - 1, i] * 
               dp[n * 2 - 2, k - i]; 
    
  
    return ans; 
  
// Driver code 
static public void Main ()
{
    int n = 2; 
    int k = 2; 
    long ans = bishop_placements(n, k); 
    Console.WriteLine(ans); 
}
}
  
// This code is contributed by akt_mit

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php 
// PHP implementation of the approach
  
// returns the number of squares
// in diagonal i
function squares($i)
{
    if (($i & 1) == 1)
        return intval($i / 4) * 2 + 1;
    else
        return intval(($i - 1) / 4) * 2 + 2;
}
  
// returns the number of ways to fill a
// n * n chessboard with k bishops so
// that no two bishops attack each other.
function bishop_placements($n, $k)
{
    // return 0 if the number of valid 
    // places to be filled is less than 
    // the number of bishops
    if ($k > 2 * $n - 1)
        return 0;
  
    // dp table to store the values
    $dp = array_fill(0, $n * 2,
          array_fill(0, $k + 1, NULL));
  
    // Setting the base conditions
    for ($i = 0; $i < $n * 2; $i++)
        $dp[$i][0] = 1;
    $dp[1][1] = 1;
  
    // calculate the required number of ways
    for ($i = 2; $i < $n * 2; $i++)
    {
        for ($j = 1; $j <= $k; $j++)
            $dp[$i][$j] = $dp[$i - 2][$j] + 
                          $dp[$i - 2][$j - 1] * 
                             (squares($i) - $j + 1);
    }
  
    // stores the answer
    $ans = 0;
    for ($i = 0; $i <= $k; $i++)
    {
        $ans += $dp[$n * 2 - 1][$i] *
                $dp[$n * 2 - 2][$k - $i];
    }
  
    return $ans;
}
  
// Driver code
$n = 2;
$k = 2;
$ans = bishop_placements($n, $k);
echo $ans;
  
// This code is contributed by ita_c
?>

chevron_right


Output:

4


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.