-
Notifications
You must be signed in to change notification settings - Fork 2
/
1005 - Rooks(DP).c
65 lines (61 loc) · 1.67 KB
/
1005 - Rooks(DP).c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<stdio.h>
#include<string.h>
#define ll long long
/**
consider a board (N-1)x(N-1) in which we put K rooks
what if consider NxN board to put K rooks
o o o x
o o o x
o o o x
x x x x
we can add 0, 1, or 2 rooks in our newly added cells in general cases
*/
ll dp[32][32] = {0};
ll solve(int size, int rook)
{
if(rook==0) return 1LL;
if(size<=0 || rook>size || rook<0) return 0LL;
ll ret = dp[size][rook];
if(ret!=-1) return ret;
ret = 0;
/// current size of board is NxN
/**
put 0 rook:
Just put the newly added cells blank
so result = result for (N-1)x(N-1) with K rooks
*/
ret+=solve(size-1,rook);
/**
put 1 rook:
we can put 1 rook in free row/column of (N-1)x(N-1) with (K-1) rooks
first count number of free row & column of board
(N-1)x(N-1) with (K-1) rooks
and we have an additional cell (N,N) to put one rook
*/
ll free = (size-1) - (rook-1);
free*=2;
free++;
ret+= (free*solve(size-1, rook-1));
/**
put 2 rooks:
we can put 2 rooks in free row/column of (N-1)x(N-1) with (K-2) rooks
first count number of free row & column of board
(N-1)x(N-1) with (K-2) rooks
NOTE that we can't put in (N,N) cell, because it will it will block
our way to put another rook
*/
free = (size-1) - (rook-2);
free*=free;
ret+= (free*solve(size-1, rook-2));
return dp[size][rook] = ret;
}
int main()
{
memset(dp, -1, sizeof dp);
int tc, cs=1,n,k;
scanf("%d",&tc);
while(tc--){
scanf("%d%d",&n, &k);
printf("Case %d: %lld\n", cs++, (k>n) ? 0LL : solve(n,k));
}
}