题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入格式
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出格式
所得的方案数
输入输出样例
输入 #1
3 2
输出 #1
16
分析
分析就不分析了吧,这题简直就是炮兵阵地的弱化版套上个背包啊。我直接贴代码吧。
代码如下
#include <bits/stdc++.h>
#define N 10
#define LL long long
using namespace std;
int sta[105], ret, cnt[105];
LL f[N][105][105], ans;
int w(int x){
int s = 0;
while(x){
s++;
x -= x&-x;
}
return s;
}
int main(){
int i, j, t, n, m, k, z, a, b;
scanf("%d%d", &n, &k);
for(i = 0; i < (1 << n); i++){
if(!(i & (i >> 1))){
sta[++ret] = i;
cnt[ret] = w(i);
}
}
f[0][1][0] = 1;
for(i = 1; i <= n; i++){
for(j = 1; j <= ret; j++){
if(cnt[j] > k) break;
a = sta[j];
for(t = 1; t <= ret; t++){
b = sta[t];
if(!(a & b) && !(a & (b << 1)) && !(a & (b >> 1))){
for(z = k; z >= cnt[t]; z--){
f[i][t][z] += f[i-1][j][z - cnt[t]];
}
}
}
}
}
for(i = 1; i <= ret; i++) ans += f[n][i][k];
printf("%lld", ans);
return 0;
}