Definition
Some state compression DP problems require us to record connectivity information of states. Such problems are often vividly called Plug DP or Connectivity State Compression DP. For example, counting Hamiltonian paths on grid graphs, finding the number of ways to black-white color a chessboard such that cells of the same color form a connected component, and counting spanning trees of specific graphs, etc. These problems usually require us to encode the connectivity of states and discuss how connectivity changes during state transitions.
Introduction
Domino Tiling and Contour Line DP
To review and learn new things, before starting to learn Plug DP, let's first revisit a classic problem.
Example 「HDU 1400」Mondriaan’s Dream
Problem summary: Tile an \(N\times M\) chessboard with \(1\times 2\) or \(2\times 1\) dominoes. Find the number of ways.
When \(n\) or \(m\) is not too large, such problems can be solved using state compression DP. Divide stages row by row. Let \(dp(i,s)\) denote the number of ways considering the first \(i\) rows, with the state of the \(i\)-th row being \(s\). Here each bit of state \(s\) indicates whether this position is covered by the previous row.
Another way to divide stages is cell-by-cell DP, also called contour line DP. \(dp(i,j,s)\) denotes the number of ways considering up to row \(i\), column \(j\), with the current contour line state being \(s\).
Although in cell-by-cell DP we add one dimension to the state, the transition time complexity reduces to \(O(1)\), so the overall time complexity remains unchanged. Let \(f_0\) denote the current stage's state, \(f_1\) the next stage's state, and \(u = f_0(s)\) the current enumerated function value. Then the state transition equation is as follows:
1 2 3 4 5 6 | |
Observe that the equations for "do not place" and "place vertically" can be merged.
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Exercise 「SRM 671. Div 1 900」BearDestroys
Problem summary: Given an \(n\times m\) matrix, each cell is E or S.
For a matrix, there is a scoring scheme. Scan each cell in row-major order. If the cell was previously occupied by a domino, skip.
Otherwise, try to place a domino. If the placement direction is outside the matrix or occupied by another domino, the placement fails; try the other scheme or skip.
If it's E, prioritize placing a \(1\times 2\) domino.
If it's S, prioritize placing a \(2\times 1\) domino.
The score of a matrix is the number of dominoes finally placed.
Find the sum of scores over all \(2^{nm}\) matrices.
Terminology
Stage: The order of dynamic programming execution. Results of later stages depend only on results of earlier stages (no aftereffect). Many DP problems can have multiple ways to divide stages. For example, in the knapsack problem, we can usually divide stages by items or by knapsack capacity (which loop enumerates first). In domino tiling problems, we can divide stages by rows, columns, cells, or diagonals.
Contour line: The boundary between decided and undecided states.
Plug: A plug exists in a certain direction of a cell, indicating that the cell is connected to its neighbor in that direction.
Path Model
Multiple Loops
Example
Example 「HDU 1693」Eat the Trees
Problem summary: Find the number of ways to cover an \(N\times M\) chessboard with several loops. Some positions have obstacles.
Strictly speaking, multiple loops problems do not belong to Plug DP, because we only need to record whether plugs exist, then merge and generate plugs in pairs, similar to the domino tiling problem above.
Note that for a chessboard of width \(m\), the contour line width is \(m+1\), because it includes \(m\) top plugs and \(1\) left plug. Note that after iterating through a row, the rightmost left plug is usually an invalid state. At the same time, we need to add the first left plug of the next row, which requires adjusting the current contour line state, usually by shifting all states left. We call this operation rolling roll().
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | |
Exercises
Exercise 「ZOJ 3466」The Hive II
Problem summary: Same as above, but cells become hexagons.
Single Loop
Example
Example 「Andrew Stankevich Contest 16 - Problem F」Pipe Layout
Problem summary: Find the number of ways to cover an \(N\times M\) chessboard with a single loop.
In the state representation above, each time we merge a set of connected plugs, an independent loop is generated. Thus, in this problem, we also need to distinguish connectivity between plugs (it appears!). This requires additional encoding of the state.
State Encoding
Common encoding schemes include bracket representation and minimum representation. Here we focus on the more versatile minimum representation. We use an integer array of length \(m+1\) to record the state of each plug on the contour line. \(0\) means no plug, and we agree that connected plugs are marked with the same number.
Then the following two encodings represent the same state:
0 3 1 0 1 30 1 2 0 2 1
We map all identical states to the lexicographically smallest representation. For example, in the above case, 0 1 2 0 2 1 is a minimum representation.
We use array b[] to represent the plug states on the contour line. bb[] represents, during the minimum representation encoding process, the smallest number each number is mapped to. Note that \(0\) means no plug and cannot be mapped to other values.
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
We note that plugs always appear and disappear in pairs. Thus, states like 0 1 2 0 1 2 are invalid. Valid states form a bracket sequence. In practice, valid states can be very sparse.
Handwritten Hash
In some state compression DP problems, valid states may be sparse (e.g., this problem). To optimize time and space complexity, we can use a hash table to store valid DP states. For C++ users, we can use std::unordered_map, or we can write our own, which allows flexible encapsulation of the state transition function.
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
In the above code:
MaxSZrepresents the upper bound of valid states, which can be estimated or preprocessed to a more accurate value.Primeis a large prime less thanMaxSZ.head[]pointers to the head nodes.next[]pointers to subsequent states.state[]node states.key[]node keys, which in this problem are the number of ways.clear()initialization function, similar to handwritten adjacency lists, we only need to initialize the head node pointers.push()state transition function, wheredis a global variable (for convenience), representing the increment brought by each state transition. If found,+=; otherwise, create a new node with statesand keyd.roll()after iterating through a whole row, roll the contour line.
For complexity analysis of hash tables, and the differences between open hashing and closed hashing, refer to the relevant chapters on hash tables in Introduction to Algorithms.
State Transition
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
Exercises
Exercise 「Ural 1519」Formula 1
Problem summary: Find the number of ways to cover an \(N\times M\) chessboard with a single loop. Some positions have obstacles.
Exercise 「USACO 5.4.4」Betsy's Tours
Problem summary: An \(N\times N\) square (\(N\le 7\)). Find the total number of paths from the top-left corner to the bottom-left corner passing through every cell. Although it's a single path, because the start and end are fixed, it can be transformed into a single loop problem.
Exercise 「POJ 1739」Tony's Tour
Problem summary: An \(N\times M\) chessboard. Find the total number of paths from the bottom-left corner to the bottom-right corner passing through every cell. Some positions have obstacles.
Exercise 「USACO 6.1.1」Postal Vans
Problem summary: Find the number of ways to cover a \(4\times N\) chessboard with a single directed loop. Requires high precision.
Exercise 「HNOI 2007」Amusement Park
Problem summary: Given an \(n\times m\) grid, each cell has a weight. Find any loop that maximizes the sum of weights passed through.
Exercise 「ProjectEuler 393」Migrating ants
Problem summary: Cover an \(n\times n\) square with multiple loops. Each solution with \(m\) loops contributes \(2^m\) to the answer. Find the sum of contributions over all solutions.
Single Path
Example
Example 「ZOJ 3213」Beautiful Meadow
Problem summary: An \(N\times M\) square (\(N,M\le 8\)), each grid point has a weight. Find a path that maximizes the sum of weights of covered grid points.
This is a standard single path problem. In single path problems, the encoded state may also contain unpaired independent plugs. The state transition function needs to additionally discuss the generation, merging, and disappearance of independent plugs. The generation and disappearance of independent plugs correspond to the ends of the path, so such events will not occur more than twice (once generation and once disappearance, or twice generation and once merge). Otherwise, the final result will definitely have multiple connected components.
We need to additionally record the total number of such events in the state. We can encode this information into the state (note that such extra information does not need to roll with the contour line adjustment), or we can add a dimension outside the hashTable array. In the example program below, we choose the latter.
State Transition
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | |
Exercises
Exercise 「BZOJ 2310」ParkII
Problem summary: \(m\times n\) chessboard, each grid point has a weight. Find a path coverage that maximizes the sum of weights of points passed through.
Exercise 「NOI 2010 Day2」Travel Route
Problem summary: \(n\times m\) chessboard, each cell has a 01 weight T[x][y]. Find a path coverage satisfying:
- The i-th visited cell (x, y) satisfies T[x][y]= L[i]
- One end of the path is on the boundary of the chessboard.
Find the number of feasible solutions.
Coloring Model
Besides the path model, there is another common model that requires us to color the chessboard, where adjacent nodes of the same color are considered connected. In path problems, we enumerate the direction of the current path during state transition. In coloring problems, we enumerate which color to assign to the current node. In the coloring model, there may be more than two nodes with the same connectivity in the state. But overall, it's still similar. Let's look at a classic example.
Example 「UVa 10572」Black & White
Example 「UVa 10572」Black & White
Problem summary: In an \(N\times M\) chessboard, color the uncolored grid points black or white. Require all black regions and all white regions to be connected. Also, any \(2\times 2\) sub-rectangle cannot have all cells of the same color (e.g., the situation in the figure below is illegal). Find the number of legal colorings and construct one legal coloring.
State Encoding
First consider state encoding. Without considering connectivity, it's SGU 197. Nice Patterns Strike Back, which can be directly solved with state compression DP. Now we need to incorporate both color and connectivity information in the state. Examine the state of each position on the contour line. Each Offset bits in binary describe one position on the contour line. Since there are only two colors, we use the parity of the lowest bit to represent color, and the remaining bits for connectivity.
Consider the nodes above the first row and to the left of the first column. To avoid special cases, we could introduce a third color to distinguish them. Here we observe that the connectivity information of these boundary states must be 0, so no additional encoding for a third color is needed.
In path problems, our contour line consists of \(m\) top plugs and \(1\) left plug. In this problem, because we also need to check whether the \(2\times 2\) sub-rectangle with the current cell as the bottom-right corner is legal, we need to record the color of the top-left cell. Therefore, the contour line length is still \(m+1\).
This encoding scheme still retains much redundant information (connected regions must have the same color, and the top-left cell only needs color information, not connectivity). But since we already use hash tables and minimum representation, the impact on time complexity is not significant. To reduce programming pressure, we won't refine further.
In the worst case (e.g., first row alternating black and white), each plug's connectivity information is different, so we need \(4\) bits to record connectivity, plus color information. Thus, Offset is \(5\) bits in this problem.
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Handwritten Hash
Because we need to construct any one solution, we need to add an array pre[] to the hash table to record an arbitrary predecessor of each state in the previous stage.
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
Solution Construction
With the above information, we can easily construct a solution. First, iterate through the states in the current hash table. If the number of connected components does not exceed \(2\), count it into the number of solutions. If the number of solutions is not \(0\), we use the pre array to construct a solution in reverse order. Note that at the end of each row, because we performed Roll(), the color needs to be taken from c[j+1].
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
State Transition
We denote:
cccolor of the cell currently being coloredlfcolor of the left cellupcolor of the top celllucolor of the top-left cell
We use \(-1\) to indicate no color. Next, discuss state transitions. There are three cases: merge, inherit, and generate.
State Transition - Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
For the last case, note that if a closed connected region has already been generated, we cannot use its color to color other cells; otherwise, that color would appear in two connected components. We seem to need to record this event separately. We can refer to the approach in 「ZOJ 3213」Beautiful Meadow by adding another dimension to record this event. However, leveraging the specifics of this problem, we can also handle it with a special case.
Special Case - Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Further discuss the disappearance of connected components. Whenever we color a cell, if no other cell is connected to the cell above it, a closed connected component is formed. This event can only happen in the last two columns of the last row. Otherwise, to avoid \(2\times 2\) monochromatic connected blocks, this color must appear again, except for the following case:
1 2 3 | |
We handle this case specially, so in this problem, we can lazily avoid recording whether a closed connected block has been generated.
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
Exercises
Exercise 「Topcoder SRM 312. Div1 Hard」CheapestIsland
Problem summary: Given a chessboard graph, each cell has a weight. Find the connected component with the minimum sum of weights.
Exercise 「JLOI 2009」Mysterious Creature
Problem summary: Given a chessboard graph, each cell has a weight. Find the connected component with the maximum sum of weights.
Exercise 「AtCoder Beginner Contest 211. Problem E」Red Polyomino
Problem summary: Given an \(N\times N\) chessboard, each cell initially black or white. You can choose exactly \(K\) white cells and color them red. How many coloring schemes make the red cells form a connected component?
Graph Theory Model
Example 「NOI 2007 Day2」Spanning Tree Count
Problem summary: Spanning tree counting for a special type of graph where each node is connected to its first \(k\) preceding nodes.
Example 「2015 ACM-ICPC Asia Shenyang Regional Contest - Problem E」Efficient Tree
Problem summary: Given an \(N\times M\) grid graph and edge weights between adjacent four-connected cells. For a spanning tree, each node's score is 1+[has an edge upward]+[has an edge leftward]. The spanning tree's score is the product of all nodes' scores.
Find: the minimum spanning tree's edge weight sum, and the sum of scores of all minimum spanning trees. (\(n\le 800,m\le 7\))
Practical Section
Example
Example 「HDU 4113」Construct the Great Wall
Problem summary: Construct a set of loops on an \(N\times M\) chessboard to separate all x and o.
There is a class of Plug DP problems that require constructing a set of walls on the chessboard to separate certain elements. We can call them wall construction problems. These problems can be viewed as either coloring models or path models.
In this problem, if viewed as a coloring model, we not only need to discuss the perimeter of colored regions but also check for illegal situations due to corner touching (Figure 2). Also, unlike 「UVa 10572」Black & White, this problem requires the wall to be a simple polygon. Thus, the following donut shape is illegal in this problem.
1 2 3 4 | |
Therefore, we use the path model and transform it into a single loop to handle.
We perform DP along the intersections of the chessboard (thus width and height increase by \(1\)). During each transition, we need to ensure all x are outside the loop and o are inside the loop. So we also need to maintain whether the current position is inside the loop. For this information, we can add a dimension, or directly count the parity of the number of down plugs encountered on the contour line up to this position (ray casting method).
Example Code
```cpp
include
include
using namespace std;
define REP(i, n) for (int i = 0; i < n; ++i)
template
constexpr int N = 10, M = N; constexpr int offset = 3, mask = (1 << offset) - 1; int n, m; int d; constexpr int INF = 0x3f3f3f3f; int b[M + 1], bb[M + 1];
int encode() { int s = 0; memset(bb, -1, sizeof(bb)); int bn = 1; bb[0] = 0; for (int i = m; i >= 0; --i) {
define bi bb[b[i]]
1 2 3 | |
} return s; }
void decode(int s) { REP(i, m + 1) { b[i] = s & mask; s >>= offset; } }
constexpr int MaxSZ = 16796, Prime = 9973;
struct hashTable { int head[Prime], next[MaxSZ], sz; int state[MaxSZ]; int key[MaxSZ];
void clear() { sz = 0; memset(head, -1, sizeof(head)); }
void push(int s) { int x = s % Prime; for (int i = head[x]; ~i; i = next[i]) { if (state[i] == s) { checkMin(key[i], d); return; } } state[sz] = s, key[sz] = d; next[sz] = head[x]; head[x] = sz++; }
void roll() { REP(i, sz) state[i] <<= offset; } } H[2], H0, H1;
char A
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用