Question: How many la s are there at most when the grid of n and m is full of 1*2 squares?
A classic outline dp, Which is parsed in the white book. Here we will analyze the entire process.
The following uses a rolling array, and the memory usage is very high.
The dp process constantly updates [I, j] points so that dp [I, j] is the optimal solution of this point. Obviously, the optimal solution of the sub-problem is a necessary condition of the original problem, therefore, the dp [I, j] obtained by traversing [I, j] is the optimal solution.
// Condition for using dp: The subproblem is the best, and the previous recursive problem is the best.
Dp [I, j] indicates the maximum number of steps in the j state of row I.
Let's take a look at the status transfer process:
For [I, j] points, there are three types of status transfer:
[I, j] do not place
1. When [I, j] points are not put, K9 points must be put, otherwise the shop is not satisfied, so only when K9 = 1 is transferred to the binary value K8K7K6... k2K1K00. 0 indicates [I, j ].
[I, j] point-to-point (we only need to consider putting it up and to the left, because we want to find the optimal solution, so we can consider it)
2. You must transfer K9 = 0 to K8K7K6... K1K0 1.
3. Move it to the left. At this time, K0 = 0 & K9 = 1 (indicating that K9 has been used up so that it can be fully filled) must be transferred to K8K7K6... K1 1 1
Several details:
1. The so-called state transfer is addition in the above
2. In the third for, the K value traverses all States with K0 as the end point, rather than the State with [I, j] as the end point.
3. For example 2, the status to be transferred (in blue) is the end point of [I, j ].
4. the operation in the program is actually: transfer all the states of [I, J-1] to [I, j], grasp this sentence can quickly understand the code
1. Traverse [I, j] points
For (I-> n)
For (j-> m)
For (k = 0-> (1 <m)-1) // traverses the status of the front vertex of [I, j]
K indicates the status of the grid in front of [I, j], that is, the state of the green grid. k is expressed in binary notation, 0 indicates not to put, and 1 indicates to put
K = K9 K8 K7 K6 k5...
2. According to the above three states, all states of [I, J-1] point are transferred to [I, j] Point
3. Based on the meaning of the dp array, the conclusion should be dp [n-1] [(1 <m)-1], the scrolling array is used here, so the answer is dp [cur] [(1 <m)-1] // cur to indicate the current row
# Include <stdio. h> # include <string. h> # define N 12 # define ll long ll dp [2] [1 <N], n, m, cur; void updata (ll a, ll B) {if (B & 1 <m) dp [cur] [B ^ (1 <m)] + = dp [1-cur] [a];} int main () {ll I, j, k; while (scanf ("% lld", & n, & m), n) {if (n <m) {I = n; n = m; m = I;} memset (dp, 0, sizeof (dp); dp [0] [(1 <m) -1] = 1; cur = 0; for (I = 0; I <n; I ++) for (j = 0; j <m; j ++) {cur ^ = 1; memset (dp [cur], 0, sizeof (dp [cur]); for (k = 0; k <(1 <m ); k ++ ){ Updata (k, k <1); if (I &&! (K & (1 <m-1) updata (k, (k <1) ^ (1 <m) ^ 1); if (j &&! (K & 1) updata (k, (k <1) ^ 3); // binary (k 0) the last two digits of the string are changed to 1} printf ("% lld \ n", dp [cur] [(1 <m)-1]);} return 0 ;}