1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 using namespace std;
6 int n,m,cnt=1,tot=0;
7 int map[105],dp[105][100][100],mark[105],num[105];//map保存图的0101模式//dp第i行在状态j前一行状态为k时 最多...//mark标记是否为可行状态
8 char s[15];
9
10 void init()
11 {
12 int i,maxx=(1<<m);
13 for (i=0;i<maxx;i++)
14 if ( (!(i&(i<<1))) && (!(i&(i<<2))) )
15 {
16 mark[++tot]=i;
17 int t=i;
18 while(t) num[tot]+=(t&1),t>>=1;
19 }
20 }
21 bool OK(int a,int b){return !(mark[a]&map[b]);}//如果有1在一块儿,!()返回0
22
23 int main()
24 {
25 int i,j,ans=-1;
26 scanf("%d%d",&n,&m);
27 memset(dp,0,sizeof(dp));
28 init();
29 gets(s);
30 for (i=1;i<=n;i++)
31 {
32 gets(s);
33 for (j=1;j<=m;j++)
34 if (s[j-1]=='H')
35 map[i]+=(1<<(m-j));
36 }
37
38 for(i=1;i<=tot;i++) if(OK(i,1)) dp[1][i][0]=num[i],ans=max(ans,dp[1][i][0]);//预处理第1行
39
40 for(i=1;i<=tot;i++)//预处理第2行
41 {
42 if(!OK(i,2))continue;
43 for(j=1;j<=tot;j++) if(OK(j,1) && (!(mark[i]&mark[j]))) dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+num[i]),ans=max(ans,dp[2][i][j]);
44 }
45
46 for(i=3;i<=n;i++)
47 for(int now=1;now<=tot;now++)//枚举本行
48 {
49 if(!OK(now,i))continue;
50 for(int last=1;last<=tot;last++)//枚举上一行
51 {
52 if(mark[now]&mark[last])continue;
53 if(!OK(last,i-1))continue;
54 for(int llast=1;llast<=tot;llast++)//枚举上上行
55 {
56 if( (mark[now]&mark[llast]) || (mark[last]&mark[llast]) )continue;
57 if(!OK(llast,i-2))continue;
58 dp[i][now][last]=max(dp[i][now][last],dp[i-1][last][llast]+num[now]);
59 }
60 }
61 }
62 for(int now=1;now<=tot;now++)
63 for(int last=1;last<=tot;last++)ans=max(ans,dp[n][now][last]);
64 printf("%d
",ans);
65 return 0;
66 }