题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
注:数据有加强(2018/4/25)
输入格式
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出格式
所得的方案数
输入输出样例
输入 #1
3 2
输出 #1
16
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e3;
int a[maxn][maxn];
ll dp[20][maxn][20];
int vis[maxn];
int need[maxn];
int n, k, mx;
void init() {
cin >> n >> k;
mx = (1 << n) - 1;
for(int i = 0; i <= mx; i++) {
if((i & (i << 1)) == 0)
vis[i] = true;
}
for(int i = 0; i <= mx; i++) {
int tem = i;
while(tem) {
if((tem & 1) == 1)
need[i]++;
tem >>= 1;
}
}
}
void solve() {
for(int i = 0; i <= mx; i++) {
if(vis[i] && need[i] <= k)
dp[1][i][need[i]] = 1;
}
for(int i = 2; i <= n; i++) {
for(int j = 0; j <= mx; j++) {
if(vis[j]) {
for(int s = 0; s <= mx; s++) {
if(vis[s] == 0)
continue;
if((s & j))
continue;
if((j & (s << 1)))
continue;
if((j & (s >> 1)))
continue;
for(int l = 0; l <= k; l++) {
if(l < need[j])
continue;
dp[i][j][l] = (dp[i][j][l] + dp[i - 1][s][l - need[j]]); }
}
}
}
}
ll ans = 0;
for(int i = 0; i <= mx; i++) {
ans += dp[n][i][k];
}
cout << ans << endl;
}
int main() {
init();
solve();
return 0;
}