Weak Queens
A weak queen on a chessboard attacks only the 8 adjacent squares (like a king). Let f(n) be the number of ways to place n non-attacking weak queens on an n x n board with exactly one queen per row....
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The classical
Let’s define a
Let \(Q(n,w)\) be the number of ways \(n\) weak queens with weakness factor \(w\) can be placed on an \(n \times n\) board so that no two queens threaten each other. It can be shown, for example, that \(Q(4,0)=2\), \(Q(4,2)=16\) and \(Q(4,3)=256\).
Let \(S(n)=\displaystyle \sum _{w=0}^{n-1} Q(n,w)\).
Let \(S(n)=\displaystyle \sum _{w=0}^{n-1} Q(n,w)\)
Find \(S(14)\).
Problem 534: Weak Queens
Mathematical Foundation
Theorem 1 (Reduction to Constrained Permutations). A placement of non-attacking weak queens, one per row, on an board is valid if and only if the column assignment satisfies for all .
Proof. Since there is exactly one queen per row, the column assignments must be distinct, forming a permutation. A weak queen in row , column attacks the 8 cells at Chebyshev distance 1. Two queens in rows and can attack each other only if and . Since queens are in distinct rows, the only potentially attacking pairs are in consecutive rows and , requiring . The non-attacking condition is therefore for all consecutive .
Theorem 2 (Bitmask DP Correctness). Define as the number of ways to fill rows using column set , with the last queen in column . Then
where the recurrence is
Proof. The DP state captures exactly the information needed: which columns have been used (the bitmask ensures the permutation property) and which column was most recently placed (needed to enforce the constraint). The base case assigns for each column . Each transition extends a valid partial placement by one row. By induction on , counts all valid partial placements of queens using columns with the last in column . Summing over all when gives .
Editorial
A weak queen attacks only adjacent squares (king moves). Place n non-attacking weak queens on an n x n board, one per row. Constraint: queens in adjacent rows must be >= 2 columns apart. Compute sum_{n=1}^{12} f(n) using bitmask DP.
Pseudocode
if n == 1: return 1
if n <= 3: return 0
dp[mask][last_col] = count of valid placements
dp = map from (mask, col) -> integer, initially 0
For c from 0 to n-1:
dp[(1 << c, c)] = 1
For row from 1 to n-1:
new_dp = empty map
For each each (mask, prev_c) in dp with popcount(mask) == row:
For c from 0 to n-1:
If mask & (1 << c) != 0 then continue
If |c - prev_c| < 2 then continue
new_dp[(mask | (1 << c), c)] += dp[(mask, prev_c)]
merge new_dp into dp
Return sum of dp[(2^n - 1, c)] for all c
Return sum of F(n) for n = 1 to 12
Complexity Analysis
- Time: per value of . For each of the states, we try transitions. For : operations. Summing over is dominated by the term.
- Space: for the DP table. For : entries.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
* Problem 534: Weak Queens
*
* Place n non-attacking weak queens (king-move attacks only) on n x n board.
* One queen per row. Queens in adjacent rows must differ by >= 2 columns.
*
* Bitmask DP: dp[mask][last_col] = count of ways.
* Time: O(n^2 * 2^n).
*/
ll f(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
int total_masks = 1 << n;
// dp[mask][last_col]
vector<vector<ll>> dp(total_masks, vector<ll>(n, 0));
// Row 0: place queen in any column
for (int c = 0; c < n; c++) {
dp[1 << c][c] = 1;
}
for (int row = 1; row < n; row++) {
vector<vector<ll>> new_dp(total_masks, vector<ll>(n, 0));
for (int mask = 0; mask < total_masks; mask++) {
if (__builtin_popcount(mask) != row) continue;
for (int prev_c = 0; prev_c < n; prev_c++) {
if (dp[mask][prev_c] == 0) continue;
for (int c = 0; c < n; c++) {
if (mask & (1 << c)) continue;
if (abs(c - prev_c) < 2) continue;
new_dp[mask | (1 << c)][c] += dp[mask][prev_c];
}
}
}
for (int mask = 0; mask < total_masks; mask++) {
for (int c = 0; c < n; c++) {
dp[mask][c] += new_dp[mask][c];
}
}
}
int full = (1 << n) - 1;
ll result = 0;
for (int c = 0; c < n; c++) {
result += dp[full][c];
}
return result;
}
int main() {
ll total = 0;
for (int n = 1; n <= 12; n++) {
ll val = f(n);
printf("f(%d) = %lld\n", n, val);
total += val;
}
printf("Sum = %lld\n", total);
assert(total == 3884);
cout << total << endl;
return 0;
}
"""
Problem 534: Weak Queens
A weak queen attacks only adjacent squares (king moves).
Place n non-attacking weak queens on an n x n board, one per row.
Constraint: queens in adjacent rows must be >= 2 columns apart.
Compute sum_{n=1}^{12} f(n) using bitmask DP.
"""
from collections import defaultdict
# --- Method 1: Bitmask DP ---
def f_bitmask(n: int):
"""Count placements via bitmask DP. O(n^2 * 2^n)."""
if n == 0:
return 0
# dp[(mask, last_col)] = count
dp = defaultdict(int)
for c in range(n):
dp[(1 << c, c)] = 1
for row in range(1, n):
new_dp = defaultdict(int)
for (mask, prev_c), count in dp.items():
if bin(mask).count('1') != row:
continue
for c in range(n):
if mask & (1 << c):
continue
if abs(c - prev_c) < 2:
continue
new_dp[(mask | (1 << c), c)] += count
for key, val in new_dp.items():
dp[key] += val
full_mask = (1 << n) - 1
return sum(v for (mask, _), v in dp.items() if mask == full_mask)
# --- Method 2: Backtracking (verification) ---
def f_backtrack(n: int):
"""Count placements via backtracking."""
count = [0]
cols = []
def solve(row):
if row == n:
count[0] += 1
return
for c in range(n):
if c in cols:
continue
if row > 0 and abs(c - cols[-1]) < 2:
continue
cols.append(c)
solve(row + 1)
cols.pop()
solve(0)
return count[0]
# --- Compute and verify ---
results = {}
for n in range(1, 13):
val = f_bitmask(n)
results[n] = val
if n <= 9:
assert val == f_backtrack(n), f"Mismatch at n={n}: {val} vs {f_backtrack(n)}"
print(f"f({n}) = {val}")
total = sum(results.values())
print(f"Sum = {total}")
assert total == 3884, f"Expected 3884, got {total}"