题解:互不侵犯
作者:互联网
题目
题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入格式
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出格式
所得的方案数
输入输出样例
输入
3 2
输出
16
解析:
首先定义状态:dp[i][j][k] 表示 第i行 状态j(有1的地方有国王,没有1的地方没有国王) 放了k个国王。
然后预处理:找到所有可以符合条件的存在一个数组里。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 12;
long long dp[N][1 << N][N * N];
int n,k,cnt;
int s[1 << N],num[1 << N];
long long ans = 0;
int main()
{
scanf("%d %d" ,&n,&k);
for(int i = 0;i < (1 << n); i++){
if(i & (i << 1)) continue;
int sum = 0;
for(int end = 0;end < n; end++){
if(i & (1 << end)) sum++;
}
s[++cnt] = i;
num[cnt] = sum;
}
dp[0][1][0] = 1;
for(int i = 1;i <= n; i++){
for(int j = 1;j <= cnt; j++){
for(int p = 0;p <= k; p++){
for(int end = 1;end <= cnt; end++){
if(!(s[end] & s[j]) && !(s[end] & (s[j] << 1)) && !(s[end] & (s[j] >> 1)) ){
dp[i][j][p] += dp[i - 1][end][p - num[j]];
}
}
}
}
}
for(int i = 1;i <= cnt; i++){
ans += dp[n][i][k];
}
printf("%lld" ,ans);
return 0;
}
标签:格子,互不侵犯,int,题解,long,dp,格式,国王 来源: https://www.cnblogs.com/Crazyman-W/p/14765975.html