题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。 ( 1 <=N <=9, 0 <= K <= N * N)
暴力
初见此题以为是八皇后的改版八国王,拿起来直接深搜回溯,见暴力代码:
1 |
|
果然TLE三个点,回头一看数据大小,想来自己还是sometimes naive…
动态规划正解
既然是动态规划,就要考虑好状态和状态转移方程,虽然对于我这个蒟蒻来说找到这个状态并不容易。
我们用一个三维数组d[sta][t][kk]
来表示此状态的摆放方案数,其中sta
表示这一行的状态(那些点),t
表示处于哪一行,kk
表示剩余几个国王还没用
这样定义状态的话就不难想出状态转移方程了,我们枚举剩余的kk
个国王在下一行的状态,来进行状态转移,这样我们还要对于剩余kk
个国王在一行中如何排放进行预处理,用m
数组维护,因此得到递归模式的方程:d[sta][t][kk]+=dfs(m[i],t+1,kk-tt)
既然是递归,我们就要考虑递归边界,显然递归边界是t==n
时,若kk==0
则多一种情况(返回1),否则返回0
预处理函数:
1 | void pre(int x,int t,int tot2) { |
动态规划dfs
1 | long long dfs(int sta,int t,int kk) { |
简洁明了的主函数:
1 | int main() { |