Little King [State Compression DP]

topic description

Put k kings on an n×n chessboard, the kings can attack 8 adjacent grids, and find the total number of schemes that prevent them from attacking each other.

input format

A total of one line, containing two integers n and k.

output format

A total of one line, indicating the total number of solutions, if it cannot be placed, output 0.

data range

1 ≤ n ≤ 10,
0 ≤ k ≤ n ^ 2

Input sample:

3 2

Sample output:

16

topic ideas

This question is very similar to the idea of ​​multiple backpacks. Using dfs will time out.

This can be optimized with dp's binary.

Consider a binary 1 representing a king.

1. There cannot be adjacent 1s in the i-th line, such as 6 and its base is 110, which does not meet the meaning of the question.

2. Comparing line i with line i-1, because the meaning of the question says that the surrounding 8 bits 1 0 and 0 1 or 01 and 1 0 do not conform to the meaning of the question.

Considering that this problem is basically solved here.

Problem-solving code:

#include<bits/stdc++.h>
using namespace std;
int cnt = 0;
int s[1 << 12];
int num[1 << 12];
long long f[12][144][1 << 12];//前 i行 有 多少个国王 当在i + 1行时的国王个数是否和前面的第i行相容
int main() {
	int n, k;
	cin >> n >> k;//n行 k个国王
	//预处理 防止相邻的国王在一起 用二进制表示的话 如 i = 6  110 不符合要求 
	for (int i = 0; i < (1 << n); i++) {
		if (!(i & i >> 1)) {
			s[cnt++] = i; 
			for (int j = 0; j < n; j++) {
				num[i] += (i >> j & 1);//计算国王的个数
			}
		}
	}
	f[0][0][0] = 1;
	for (int i = 1; i <= n + 1; i++) { //行数
		for (int j = 0; j <= k; j++) { //放的国王数目
			for (int a = 0; a < cnt; a++) { // 第i行
				for (int b = 0; b < cnt; b++) { //i - 1行 
					int c = num[s[a]];
					if ((j >= c) && !(s[a] & s[b]) && !(s[b] & (s[a] << 1)) && !(s[b] & (s[a] >> 1))) {
						f[i][j][a] += f[i-1][j - c][b];
					}
				}
			}
		}
	}
	cout << f[n + 1][k][0]; //这样子处理避免了还要累加的情况 在f在直接进行了 
	return 0;
}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/128558482