Artillery positions
Time limit:2000 ms |
|
Memory limit:65536 K |
Total submissions:15275 |
|
Accepted:5749 |
Description The generals of the Headquarters intend to deploy their artillery troops on the grid map of N * m. A n * m map consists of N rows and M columns. Each grid of the map may be a mountain (represented by "H") or a plain (represented by "p ), for example. A maximum of one artillery unit can be deployed on each plain terrain (the artillery unit cannot be deployed on the mountain). The black area of an artillery unit in the attack range on the map is shown:
If an artillery force is deployed on the gray plain marked by the map, the Black Grid in the figure indicates the area to which it can attack: two grids along the horizontal left and right, the two cells are vertical and vertical. No other white mesh attacks can be found on the graph. The artillery attack range is not affected by the terrain. Now, the generals plan how to deploy artillery troops to prevent accidental injuries (ensure that no two artillery troops can attack each other, that is, no artillery force is within the attack scope of other Artillery Forces.) the maximum number of Artillery Troops in our army can be placed in the whole map area.Input The first line contains two positive integers separated by spaces, representing N and m respectively; In the next n rows, each row contains M consecutive characters ('P' or 'H') with no spaces in the middle. Represent the data of each row in the map in order. N <= 100; m <= 10.Output Only one row contains an integer k, indicating the maximum number of artillery troops that can be placed.Sample Input 5 4PHPPPPHHPPPPPHPPPHHP Sample output 6 Source Noi 01 |
Ideas:
The status must be set to three because it is related to the preceding two States because the artillery attack range affects the next three rows. The DP [I] [J] [k] indicates that the status of row I is K, the maximum number of artillery when the I-1 state is J. State transition equation:
DP [I] [J] [k] = max (DP [I] [J] [K], DP [I-1] [l] [J] + sum [k]); sum [k] is the number of 1 in K State;
# Include <iostream> # include <stdio. h> # include <string. h> # define max (A, B) (a)> (B )? (A) :( B) using namespace STD; int DP [101] [65] [65]; // DP [I] [J] [k] indicates the maximum number of artillery tasks in the upstream status of I to that in the upstream status of J. K. Int State [105]; // The Int sum [105] State that can be put when a row is recorded; // records the number of artillery int maze [105] corresponding to each State. // read the map int n, m, CNT; int isok (int x) on each line. // you can determine whether a conflict exists in each line. {If (X & (x> 1 )) // determine whether there are adjacent artillery return 0; If (X & (x> 2) // determine whether there are artillery return 0; return 1 ;} int getone (int x) // calculates the number of each state 1. that is, the number of Artillery Forces {int one = 0; while (x> 0) {If (X & 1) One ++; X >>= 1 ;} return one ;} int main () {int I, j, Now, pre, PPRE, ans; char C; while (~ Scanf ("% d", & N, & M) {getchar (); CNT = 0; for (I = 0; I <(1 <m ); I ++) if (isok (I) // preprocessing. first, obtain a valid row of State {State [CNT] = I; sum [CNT ++] = getone (I);} ans = 0; memset (maze, 0, sizeof maze ); memset (DP, 0, sizeof DP); for (I = 1; I <= N; I ++) {for (j = 0; j <m; j ++) // process the map. convert the map to the 01 sequence {scanf ("% C", & C); If (C = 'H') // if it is H, it is recorded as 1. this makes it easy to determine whether a map conflicts with maze [I] = maze [I] | (1 <j) ;}getchar () ;}for (I = 0; I <CNT; I ++) if (! (State [I] & maze [1]) // initialize the first line DP [1] [0] [I] = sum [I]; for (I = 2; I <= N; I ++) {for (now = 0; now <CNT; now ++) // enumerate the state of the row {If (State [now] & maze [I]) // determine whether the State of the row conflicts with the map continue; For (pre = 0; Pre <CNT; pre ++) // enumerate the previous row {If (State [pre] & maze [I-1]) continue; If (State [now] & State [pre]) // whether this row conflicts with the previous row. Continue; For (PPRE = 0; PPRE <CNT; PPRE ++) // enumerate the upper row {If (State [PPRE] & State [now]) continue; If (State [PPRE] & State [pre]) continue; if (State [PPRE] & maze [I-2]) continue; DP [I] [pre] [now] = max (DP [I] [pre] [now], DP [I-1] [PPRE] [pre] + sum [now]) ;}}}for (I = 0; I <CNT; I ++) for (j = 0; j <CNT; j ++) if (DP [N] [I] [J]> ans) ans = DP [N] [I] [J]; printf ("% d \ n", ANS);} return 0 ;}