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

06 May, 2021
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:  
C++
Java
Python3
C#
PHP
Javascript
// CPP implementation of the approach#include<bits/stdc++.h>using namespace std; // returns the number of squares in diagonal iint 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.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[n * 2][k + 1];     // Setting the base conditions    for(int i = 0; i < n * 2; i++)    {        for(int j = 0; j < k + 1; j++)        {            dp[i][j] = 0;        }         }    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 codeint main(){    int n = 2;    int k = 2;    long ans = bishop_placements(n, k);    cout << (ans);} // This code is contributed by Rajput-Ji
// 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);    }}
# Python 3 implementation of the approach # returns the number of squares in# diagonal idef 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 codeif __name__ == '__main__':    n = 2    k = 2    ans = bishop_placements(n, k)    print(ans) # This code is contributed by# Sanjit_Prasad
// C# implementation of the approachusing System; class GFG{ // returns the number of squares// in diagonal istatic 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 codestatic 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
<?php// PHP implementation of the approach // returns the number of squares// in diagonal ifunction 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?>
<script>     // Javascript implementation of the approach         // returns the number of squares    // in diagonal i    function squares(i)    {        if ((i & 1) == 1)            return parseInt(i / 4, 10) * 2 + 1;        else            return parseInt((i - 1) / 4, 10) * 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        let dp = new Array(n * 2);         // Setting the base conditions        for (let i = 0; i < n * 2; i++)        {            dp[i] = new Array(k + 1);            for(let j = 0; j < k + 1; j++)            {                dp[i][j] = 0;            }            dp[i][0] = 1;        }        dp[1][1] = 1;         // calculate the required        // number of ways        for (let i = 2; i < n * 2; i++)        {            for (let j = 1; j <= k; j++)                dp[i][j] = dp[i - 2][j] +                           dp[i - 2][j - 1] *                            (squares(i) - j + 1);        }         // stores the answer        let ans = 0;        for (let i = 0; i <= k; i++)        {            ans += dp[n * 2 - 1][i] *            dp[n * 2 - 2][k - i];        }         return ans;    }         let n = 2;    let k = 2;    let ans = bishop_placements(n, k);    document.write(ans); </script>
4
 
jit_t
Sanjit_Prasad
ukasp
Rajput-Ji
divyesh072019
Technical Scripter 2018
Dynamic Programming
Technical Scripter
Dynamic Programming
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum size square sub-matrix with all 1s
Optimal Substructure Property in Dynamic Programming | DP-2
Optimal Binary Search Tree | DP-24
Min Cost Path | DP-6
Maximum Subarray Sum using Divide and Conquer algorithm
Greedy approach vs Dynamic programming
Maximum sum such that no two elements are adjacent
Word Break Problem | DP-32
3 Different ways to print Fibonacci series in Java
Top 50 Dynamic Programming Coding Problems for Interviews