BZOJ1087: [SCOI2005]互不侵犯King

1087: [SCOI2005]互不侵犯King

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4772  Solved: 2769
[Submit][Status][Discuss]

Description

在N×N的棋盘里面放K个国王，使他们互不攻击，共有多少种摆放方案。国王能攻击到它上下左右，以及左上

Input

只有一行，包含两个数N，K （ 1 <=N <=9, 0 <= K <= N * N）

方案数。

3 2

16

Source

dp[i][j][l]表示第i行，前i行有j个国王，第i行状态标号为l

``` 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <algorithm>
6 #include <cmath>
7 #include <queue>
8 #include <vector>
9 #define min(a, b) ((a) < (b) ? (a) : (b))
10 #define max(a, b) ((a) > (b) ? (a) : (b))
11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
12 inline void swap(long long &a, long long &b)
13 {
14     long long tmp = a;a = b;b = tmp;
15 }
16 inline void read(long long &x)
17 {
18     x = 0;char ch = getchar(), c = ch;
19     while(ch < ‘0‘ || ch > ‘9‘) c = ch, ch = getchar();
20     while(ch <= ‘9‘ && ch >= ‘0‘) x = x * 10 + ch - ‘0‘, ch = getchar();
21     if(c == ‘-‘)x = -x;
22 }
23
24 const long long INF = 0x3f3f3f3f;
25
26 long long n,k,dp[10][82][1 << 9];
27 //dp[i][j][l]表示第i行放j个国王状态为state[l]的方案数
28
29 long long state[1 << 9], tot, g[1 << 9][1 << 9], num[1 << 9];
30
31 int main()
32 {
33     read(n), read(k);
34     long long ma = 1 << n;
35     for(register long long i = 0;i < ma;++ i)
36         if(!(i & (i << 1)) && !(i & (i >> 1)))
37         {
38             state[++ tot] = i;
39             long long tmp = i;
40             for(;tmp;tmp >>= 1) num[tot] += (tmp & 1);
41         }
42     for(register long long i = 1;i <= tot;++ i)
43         for(register long long j = i;j <= tot;++ j)
44             if(!(state[i] & (state[j] << 1)) && !(state[i] & (state[j] >> 1)) && !(state[i] & state[j]))
45                 g[i][j] = g[j][i] = 1;
46     for(register long long i = 1;i <= tot;++ i) if(num[i] <= k) dp[1][num[i]][i] = 1;
47     for(register long long i = 1;i < n;++ i)
48         for(register long long j = 0;j <= k;++ j)
49             for(register long long l = 1;l <= tot;++ l)
50                 if(num[l] <= j)
51                     for(register long long r = 1;r <= tot;++ r)
52                         if(g[l][r] && j + num[r] <= k)
53                             dp[i + 1][j + num[r]][r] += dp[i][j][l];
54     long long ans = 0;
55     for(register long long i = 1;i <= tot;++ i)
56         ans += dp[n][k][i];
57     printf("%lld", ans);
58     return 0;
59 } ```
BZOJ1087

BZOJ1087: [SCOI2005]互不侵犯King

(0)
(0)

0条

© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4