Problem (Black 1946, Gamow–Stern 1958). Remove two diagonally opposite corners of a chessboard. Can the remaining 62 squares be tiled by 31 dominoes?
Answer. No: every domino covers one white and one black square, but both removed corners have the same colour, leaving 32 of one colour and 30 of the other. Colouring arguments are the main tool for “impossible” tilings; for “possible” ones, a construction or a counting DP.
| Question | Answer | Tool |
|---|---|---|
| minus two opposite corners, dominoes | impossible | chessboard colouring |
| minus one white and one black square, dominoes | always possible (Gomory) | Hamiltonian cycle of the board |
| by strips | possible iff or | colouring by |
| minus one square, strips | possible iff the hole is at (0-indexed) | two diagonal 3-colourings |
| minus any square, L-trominoes | always possible | divide and conquer, see Tromino Tiling |
| number of domino tilings of | profile DP, Kasteleyn’s formula | |
| domino tilings of a region with holes | count by profile DP ; existence = perfect matching | Profile DP, Bipartite Matching |
// Number of domino tilings of a grid with blocked cells '#', broken-profile DP in O(n m 2^m).
// Bit j of the mask: the next unprocessed cell in column j is already covered.
ll dominoTilings(const vector<string>& g) {
int n = sz(g), m = sz(g[0]); vector<ll> dp(1 << m, 0), nd(1 << m); dp[0] = 1;
for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) {
fill(all(nd), 0);
for (int mask = 0; mask < (1 << m); mask++) if (ll v = dp[mask]) {
if (mask >> j & 1) { nd[mask ^ 1 << j] += v; continue; } // covered from above or the left
if (g[i][j] == '#') { nd[mask] += v; continue; }
if (i + 1 < n && g[i + 1][j] != '#') nd[mask | 1 << j] += v; // vertical domino
if (j + 1 < m && !(mask >> (j + 1) & 1) && g[i][j + 1] != '#') nd[mask | 1 << (j + 1)] += v; // horizontal
}
swap(dp, nd);
}
return dp[0];
}
// Can the free cells ('.') be tiled by 1 x k strips? Backtracking on the first free cell.
bool stripTile(vector<string>& g, int k) {
int n = sz(g), m = sz(g[0]), r = -1, c = -1;
for (int i = 0; i < n && r < 0; i++) for (int j = 0; j < m; j++) if (g[i][j] == '.') { r = i, c = j; break; }
if (r < 0) return true;
for (int dir = 0; dir < 2; dir++) { // the first free cell must be the left or top end of its strip
bool ok = true;
for (int t = 0; t < k && ok; t++) { int x = r + dir * t, y = c + (1 - dir) * t; ok = x < n && y < m && g[x][y] == '.'; }
if (!ok) continue;
for (int t = 0; t < k; t++) g[r + dir * t][c + (1 - dir) * t] = '#';
bool res = stripTile(g, k);
for (int t = 0; t < k; t++) g[r + dir * t][c + (1 - dir) * t] = '.';
if (res) return true;
}
return false;
}Proof: Gomory's theorem
The board has a Hamiltonian cycle in its grid graph: go right along row 0, then snake through rows inside columns (row 1 leftwards, row 2 rightwards, …, row 7 leftwards, ending at ), and return up column 0. Consecutive cells of the cycle have opposite colours, so two cells of opposite colours sit at positions of the cycle that differ by an odd number. Removing them cuts the cycle into two arcs (one is empty if they are adjacent), each with an even number of cells; pairing consecutive cells along each arc tiles it with dominoes. The same proof works for every board with even and (the snake needs an odd number of rows), hence for every board with even and . Checked with the DP: all removals on and give a positive count.
Proof: 1 × k strips tile m × n iff k divides m or n
If , tile each row with horizontal strips; similarly for . Conversely colour cell with . A strip covers consecutive values of , hence one cell of each colour, so a tileable region has equally many cells of every colour. Write , with and, by symmetry, . The board splits into a block (each column holds consecutive values of : equal counts), an block (equal counts by rows), and an corner. In the corner, colour appears exactly times (sum has solutions with , , and is out of range). Colour appears times (sum exactly , since ; solutions ). So the corner, and hence the whole board, has unequal colour counts: no tiling.
Proof: the 1 × 3 strips on 8 × 8 minus one square
Colour by and separately by ; a horizontal or vertical strip covers each colour once in both colourings. On the sum occurs times, so residue occurs times and residues and occur 21 times each. A tiling of the 63 remaining cells covers each colour 21 times. So the hole must be a cell with . For there are cells, so residue occurs times and the hole has . Together , i.e. , and : the hole is at , four cells. For each of them
stripTilefinds a tiling, and for the other 60 it reports none.
The number of domino tilings of an board is given by Kasteleyn’s formula (Kasteleyn; Temperley and Fisher, 1961), proved with Pfaffians:
stated here without proof; it agrees with dominoTilings for all (, and it grows like with Catalan’s constant ).