Ways to place K bishops on an N×N chessboard so that no two attack
Last Updated :
08 Mar, 2023
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++
#include<bits/stdc++.h>
using namespace std;
int squares( int i)
{
if ((i & 1) == 1)
return i / 4 * 2 + 1;
else
return (i - 1) / 4 * 2 + 2;
}
long bishop_placements( int n, int k)
{
if (k > 2 * n - 1)
return 0;
long dp[n * 2][k + 1];
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;
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);
}
}
long ans = 0;
for ( int i = 0; i <= k; i++)
{
ans += dp[n * 2 - 1][i] * dp[n * 2 - 2][k - i];
}
return ans;
}
int main()
{
int n = 2;
int k = 2;
long ans = bishop_placements(n, k);
cout << (ans);
}
|
Java
class GFG {
static int squares( int i)
{
if ((i & 1 ) == 1 )
return i / 4 * 2 + 1 ;
else
return (i - 1 ) / 4 * 2 + 2 ;
}
static long bishop_placements( int n, int k)
{
if (k > 2 * n - 1 )
return 0 ;
long [][] dp = new long [n * 2 ][k + 1 ];
for ( int i = 0 ; i < n * 2 ; i++)
dp[i][ 0 ] = 1 ;
dp[ 1 ][ 1 ] = 1 ;
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 );
}
long ans = 0 ;
for ( int i = 0 ; i <= k; i++) {
ans += dp[n * 2 - 1 ][i] * dp[n * 2 - 2 ][k - i];
}
return ans;
}
public static void main(String[] args)
{
int n = 2 ;
int k = 2 ;
long ans = bishop_placements(n, k);
System.out.println(ans);
}
}
|
Python3
def squares(i):
if ((i & 1 ) = = 1 ):
return int (i / 4 ) * 2 + 1
else :
return int ((i - 1 ) / 4 ) * 2 + 2
def bishop_placements(n, k):
if (k > 2 * n - 1 ):
return 0
dp = [[ 0 for i in range (k + 1 )]
for i in range (n * 2 )]
for i in range (n * 2 ):
dp[i][ 0 ] = 1
dp[ 1 ][ 1 ] = 1
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 ))
ans = 0
for i in range ( 0 , k + 1 , 1 ):
ans + = (dp[n * 2 - 1 ][i] *
dp[n * 2 - 2 ][k - i])
return ans
if __name__ = = '__main__' :
n = 2
k = 2
ans = bishop_placements(n, k)
print (ans)
|
C#
using System;
class GFG
{
static int squares( int i)
{
if ((i & 1) == 1)
return i / 4 * 2 + 1;
else
return (i - 1) / 4 * 2 + 2;
}
static long bishop_placements( int n, int k)
{
if (k > 2 * n - 1)
return 0;
long [,] dp = new long [n * 2, k + 1];
for ( int i = 0; i < n * 2; i++)
dp[i, 0] = 1;
dp[1, 1] = 1;
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);
}
long ans = 0;
for ( int i = 0; i <= k; i++)
{
ans += dp[n * 2 - 1, i] *
dp[n * 2 - 2, k - i];
}
return ans;
}
static public void Main ()
{
int n = 2;
int k = 2;
long ans = bishop_placements(n, k);
Console.WriteLine(ans);
}
}
|
PHP
<?php
function squares( $i )
{
if (( $i & 1) == 1)
return intval ( $i / 4) * 2 + 1;
else
return intval (( $i - 1) / 4) * 2 + 2;
}
function bishop_placements( $n , $k )
{
if ( $k > 2 * $n - 1)
return 0;
$dp = array_fill (0, $n * 2,
array_fill (0, $k + 1, NULL));
for ( $i = 0; $i < $n * 2; $i ++)
$dp [ $i ][0] = 1;
$dp [1][1] = 1;
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);
}
$ans = 0;
for ( $i = 0; $i <= $k ; $i ++)
{
$ans += $dp [ $n * 2 - 1][ $i ] *
$dp [ $n * 2 - 2][ $k - $i ];
}
return $ans ;
}
$n = 2;
$k = 2;
$ans = bishop_placements( $n , $k );
echo $ans ;
?>
|
Javascript
<script>
function squares(i)
{
if ((i & 1) == 1)
return parseInt(i / 4, 10) * 2 + 1;
else
return parseInt((i - 1) / 4, 10) * 2 + 2;
}
function bishop_placements(n, k)
{
if (k > 2 * n - 1)
return 0;
let dp = new Array(n * 2);
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;
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);
}
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>
|
Time Complexity: O(n^2 * k), where n is the size of the chessboard and k is the number of bishops to be placed.
Space Complexity: O(n^2 * k), since we are using a 2D dp table of size n * 2 x k + 1 to store the values of the dynamic programming solution.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...