SCOI05 does not infringe on King questions, scoi05king questions
Description
Put K kings in the N × N board so that they do not attack each other. The king was able to attack it, from top to bottom, and from top to left, from top to bottom, right to bottom, and from top to bottom, a grid near each other. There were 8 grids in total.
Input Description
Only one row contains N, K (1 <= N <= 9, 0 <= K <= N * N)
Output Description
Number of solutions.
Sample Input
3 2
Sample Output
16
Data Size & Hint
1 <= N <= 9, 0 <= K <= N * N
Question
This question looks very similar to the eight queens, but in fact the search will not drop, the correct solution is to press the dp.
Phase: Use rows to divide the stages. Each row has n digits marked as 1, not 0, and one longlong row for State compression. The number of States in each row does not exceed 2n −1 . In this division phase, you can only consider the last line and this line during the transfer.
Then you canPreprocessingAll valid statuses:
First, for each row, from small to large enumeration status I. If I and (I shr 1) is 0, it indicates that status I has no adjacent king in a row, I is legal, recorded,And write down the number of kings cnt [I];
Then, for the adjacent two rows, the I, j states are enumerated from small to large. If I and j are both valid, [I and j], [I and (j shr 1)], [j and (I shr 1)]. If the three values are 0, it indicates that status I and j do not have any situation where the king is adjacent to the column or is adjacent to the diagonal line. It is legal and recorded.
StatusNote: f [p] [k] [I] indicates the number of solutions where k kings are placed in the first p row and the status of row p is I.
Transfer: Number of enumerative rows p (starting from 2), status I of the Previous row and status j of this row. If I is legal, j is legal, and the combination of I and j is legal, enumeration decision k, k indicates the number of kings in the first row, F [p] [k + cnt [j] [j] = Σ f [p − 1] [k] [I], cnt [I] <= k <= m −cnt [j]
Initialization: The first line, enumeration status I. If I is valid, f [1] [cnt [I] [I] = 1; otherwise, it is 0.
Answer: Ans = Σ f [n] [m] [I], 1 <= I <= 2n −1
Time Complexity: O (4nnk) This is the upper limit, generally not up
Space complexity: O (4n) , Enough
Code
#include <cstdio>#include <algorithm>#define ll long longusing namespace std;const int maxn = 9;int n, m, cnt[1 << maxn];ll f[maxn + 1][65][1 << maxn], ans, tot;bool sline[1 << maxn], dline[1 << maxn][1 << maxn];void read(int &a){ int f = 1; char ch = getchar(); a = 0; while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { a = a*10 + ch - 48; ch = getchar(); } a *= f;}void write(ll a){ int top = 0; char ch[maxn << 2]; if(a < 0) { putchar('-'); a = -a; } do { ch[top++] = a%10 + 48; a /= 10; } while(a); while(top--) putchar(ch[top]); putchar('\n');}void init(){ read(n); read(m); tot = (1 << n) - 1; for(int i = 0; i <= tot; ++i) if(((i >> 1) & i) == 0) { for(int j = i; j > 0; j >>= 1) cnt[i] += (j & 1); sline[i] = true; } for(int i = 0; i <= tot; ++i) if(sline[i]) for(int j = 0; j <= tot; ++j) if(sline[j]) if((i & j) == 0 && ((i >> 1) & j) == 0 && ((j >> 1) & i) == 0) dline[i][j] = true; for(int i = 0; i <= tot; ++i) if(sline[i]) f[1][cnt[i]][i] = 1;}void work(){ for(int p = 2; p <= n; ++p) for(int i = 0; i <= tot; ++i) if(sline[i]) for(int j = 0; j <= tot; ++j) if(sline[j]) if(dline[i][j]) for(int k = cnt[i]; k + cnt[j] <= m; ++k) f[p][k + cnt[j]][j] += f[p - 1][k][i]; for(int i = 0; i <= tot; ++i) ans += f[n][m][i]; write(ans);}int main(){ init(); work(); return 0;}