Idea: Status compression DP. Very classic status compression DP. The Int type is used to indicate the status of each line (if the I-bit of the int Type Binary is 1, the I-column of this line has an installation cannon ). In this case, there can be a maximum of 10 columns, so a maximum of 60 States can be obtained by calculation. DP part: DP [r] [I] [k] indicates that the state of row R is K, and the state of row R-1 is I, the maximum number of cannons that can be installed in the front R Line.
# Include <stdio. h>
# Include <string. h>
Int DP [105] [100] [100]; // DP [I] [J] [k]: "The status of row I is s [J], the I-1 line is in the S [k] State, the array opened a small point, will exceed the memory
Int s [100]; // select the state of a row s [0], s [1],..., s [k-1]
Int sum [100];
Int map [105]; // 'h''p' map [0] ~ Map [n-1]. Map [Line]: 1001 indicates hpph
Char STR [2, 105] [20];
Int Jude (int I)
{// Status s [x] indicates whether a row conflict occurs.
If (I & (I> 1 ))
Return 1;
If (I & (I> 2 ))
Return 1;
Return 0;
}
Int max (int A, int B)
{
Return A> B? A: B;
}
/* Because the maximum number of columns is not greater than 10, DP can be used for State compression.
Note: the so-called State compression, for example, phpp, can be expressed in binary 0100 and stored in decimal format as 4.
Because of its reverse symmetry, in order to facilitate compression, the above instance is compressed to 0010, expressed in 2, without affecting the solution. */
Int main ()
{
Int n, m, ANS, I, J, K, R, Q, P, num, X;
While (scanf ("% d", & N, & M )! = EOF)
{
Memset (MAP, 0, sizeof (MAP ));
For (I = 0; I <n; I ++)
{
Scanf ("% s", STR [I]);
For (j = 0; j <m; j ++)
If (STR [I] [J] = 'H ')
Map [I] = map [I] | (1 <j); // reverse the original state of line I and put it in map [I]
}
K = 0;
For (I = 0; I <(1 <m); I ++)
{
If (Jude (I) = 0)
{
S [k] = I;
Num = 0;
X = I;
While (x> 0)
{// Status 1 under s [x]
If (X & 1)
Num ++;
X> = 1;
}
Sum [k ++] = num;
}
}
Memset (DP, 0, sizeof (DP ));
// Initialize the status of 0th rows
For (I = 0; I <K; I ++)
If (! (S [I] & map [0]) // the bit where s [I] is 1. if it corresponds to a plain (0), the value after the & operation is 0.
DP [0] [I] [0] = sum [I];
// Calculate 1st ~ N-1 row status
For (r = 1; r <n; r ++)
{
For (I = 0; I <K; I ++) // enumerate the status of row r s [I]
{
If (Map [R] & S [I]) continue; // exclude the state of part of row R through terrain
For (P = 0; P <K; P ++) // enumerate the state of the row of the R-1 s [p]
{
If (s [I] & S [p]) continue; // R is not intended for contact with the R-1
For (q = 0; q <K; q ++) // enumerate the state of the row in the R-2 s [Q]
{
If (s [p] & S [Q]) continue;
If (s [I] & S [Q]) continue;
DP [r] [I] [p] = max (DP [r-1] [p] [Q] + sum [I], DP [r] [I] [p]);
}
}
}
}
Ans = 0;
For (I = 0; I <K; I ++)
For (j = 0; j <K; j ++)
Ans = max (ANS, DP [n-1] [I] [J]);
Printf ("% d \ n", ANS );
}
Return 0;
}