其他分享
首页 > 其他分享> > 题解:互不侵犯

题解:互不侵犯

作者:互联网

题目

题目描述

在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