
点击查看代码
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL;
const int N = 12, M = 1 << 10, K = 110;
int n, m;
vector<int> state;
int cnt[M];
vector<int> head[M];
LL f[N][K][M];
bool check(int x)
{
for (int i = 0; i < n; i ++)
if ((x >> i & 1) && ((x >> i + 1 & 1)))
return false;
return true;
}
int count(int x)
{
int res = 0;
for (int i = 0; i < n; i ++)
res += x >> i & 1;
return res;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < 1 << n; i ++)
if (check(i)) {
state.push_back(i);
cnt[i] = count(i);
}
for (auto a : state)
for (auto b : state) {
if ((a & b) == 0 && check(a | b))
head[a].push_back(b);
}
f[0][0][0] = 1;
for (int i = 1; i <= n + 1; i ++)
for (int j = 0; j <= m; j ++)
for (auto a : state)
for (auto b : head[a]) {
int c = cnt[a];
if (j >= c)
f[i][j][a] += f[i - 1][j - c][b];
}
cout << f[n + 1][m][0] << endl;
return 0;
}
- 状态表示
f[i][j][s] 表示所有只摆前 i 行,已经摆了 j 个国王,并且第 i 行的状态是 s 的所有方案的个数
- 状态计算
合法的状态才能转移,第 i 行只与第 i−1 行有关,合法的状态:
设第 i 行的状态为 a,第 i−1 行的状态为 b
① 不能有两个国王在同一列,即 a & b==0
② 不能有两个国王处在相邻的列,即 a | b 不能有两个连续的 1
满足上述条件的情况下:
f[i][j][a] += f[i−1][j−count(a)][b] (count(a) 表示 a 的二进制表示中 1 的个数)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)