最近,郑厂长对八皇后问题很感兴趣,拿着国际象棋研究了好几天,终于研究透了。兴奋之余,坐在棋盘前的他又开始无聊了。无意间,他看见眼前的棋盘上只摆了八个皇后,感觉空荡荡的,恰好又发现身边还有几个骑士,于是,他想把这些骑士也摆到棋盘上去,当然棋盘上的一个位置只能放一个棋子。因为受八皇后问题的影响,他希望自己把这些骑士摆上去之后,也要满足每2个骑士之间不能相互攻击。
现在郑厂长想知道共有多少种摆法,你能帮助他吗?
骑士的下法:
每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外横走或竖走一格(即走“日”字)。可以越子,没有”中国象棋”的”蹩马腿”限制。
一道简单的状态压缩dp,和皇后并没有什么关系,只是摆了皇后的地方不能摆骑士。
dp[i][num][j][k] 记录四个状态:
i 代表第 i 行
num 代表前i-1行里共有num个骑士
j 代表 i-1行的状态
k 代表 i 行的状态
转移方程 dp[i][cnt+num][k][l] += dp[i-1][num][j][k];
cnt 为当前行的骑士个数 l 代表第 i 行 ,k 代表 i - 1行,j代表 i - 2 行
直接暴力写肯定会跪,刚写出来本地运行一个用例要2秒多,加上一些简单的优化就搞定了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N;
int G[10];
int dp[10