国王 状压dp

在 N \times NN×N 的棋盘里面放 KK 个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共 88 个格子。

输入格式

只有一行,包含两个数 N, KN,K。

输出格式

所得的方案数。

样例

InputcopyOutputcopy
3 2
16

数据范围与提示

1 \le N \le 9, 0 \le K \le N \times N1≤N≤9,0≤K≤N×N

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int bits[1010],num[1010],cnt,n,m;// dp[][][] : 第几行 当前状态 总共一的个数 的方案数 
ll dp[10][1100][85];
void dfs(int now,int nu,int s) // s:一的个数 nu:第几列 now:当前状态 bits[]:记录合法状态 num[]:当前状态的一个数 
{
	if(nu >= n){
		cnt++;
		bits[cnt] = now;
		num[cnt] = s;
		return;
	}
	dfs(now,nu+1,s);
	dfs(now+(1<<nu),nu+2,s+1);
}
int main()
{
	cin >> n >> m;
	dfs(0,0,0);
	for(int i = 1;i <= cnt; i++)
		dp[1][i][num[i]] = 1;
	for(int i = 2;i <= n; i++){
		for(int j = 1;j <= cnt; j++){
			for(int k = 1;k <= cnt; k++){ 
				if(bits[j] & bits[k]) continue;
				if((bits[j]<<1 & bits[k]) || (bits[j]>>1 & bits[k])) continue;
				for(int l = num[k]; l <= m; l++){
					dp[i][k][l] += dp[i-1][j][l-num[k]];
				}
			}
		}
	}
	ll ans = 0;
	for(int i = 1;i <= cnt; i++)
		ans += dp[n][i][m];
	cout << ans;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值