//poj 1185 炮兵阵地 /* 又一道状态压缩DP ,最烦的题,没心思精简代码,1700多MS低空飞过。。。 */ #include<iostream> using namespace std; int n,m; char str[12]; int grid[102]; int dp[101][70][70]; //dp[n][i][j]表示d到第n行,第n行和第n-1行分别为状态i,j的最大炮兵数。 int state[70],c; //dfs一遍把所有状态记录下来,由于限制大,所以其实状态不多,这是本题不TLE也不MLE的关键 void dfs(int step,int s) { if (step>=m) { state[c++]=s; return ; } dfs(step+1,s); if (step>1 && (s & (1<<(step-1)) )==0 && ( s & (1<<(step-2)) )==0 || step==1 && (s & (1<<(step-1)) )==0 || step==0) dfs(step+3,s|(1<<step)); } int ones(int a) { int ans=0; for (;a;a>>=1) ans+=a&1; return ans; } bool collipse(int g1,int s1,int g2,int s2) { for (int i=0;i<m;i++) if ( (s2&(1<<i)) && (g2&(1<<i))==0 && (s1&(1<<i)) && (g1&(1<<i))==0 ) return true; return false; } int main() { while (scanf("%d%d",&n,&m)!=EOF) { c=0; dfs(0,0); memset(grid,0,sizeof(grid)); for (int i=1;i<=n;i++) { scanf("%s",str); for (int j=0;j<m;j++) if (str[j]=='H') grid[i]|=1<<j; } memset(dp,-1,sizeof(dp)); for (int i=0;i<c;i++) if ((state[i]&grid[1])==0) dp[1][i][0]=ones(state[i]); for (int i=2;i<=n;i++) { for (int j=0;j<c;j++) if ((grid[i]&state[j])==0) for (int k=0;k<c;k++) if ((grid[i-1]&state[k])==0 && !collipse(grid[i-1],state[k],grid[i],state[j])) { for (int v=0;v<c;v++) if ((state[v]&grid[i-2])==0 && !collipse(grid[i-2],state[v],grid[i-1],state[k]) && !collipse(grid[i-2],state[v],grid[i],state[j])) { if(dp[i-1][k][v]!=-1) dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][v]+ones(state[j]) ); } } } int ans=0; for (int i=0;i<c;i++) if ((grid[n-1]&state[i])==0) for (int j=0;j<c;j++) if ((grid[n]&state[j])==0 && !collipse(grid[n-1],state[i],grid[n],state[j])) ans=max(ans,dp[n][j][i]); printf("%d/n",ans); } system("pause"); return 0; }