题是看懂了,可是还是不会做,感觉太麻烦了,先放着吧。。。
#include <cstdio>
#include <cmath>
#include <cstdlib>
const int large = (int)pow( 2, 10 );
int n,m;
char map[105][15];
int dp[60][60][101];
int ST[large+1];
int len = 0;
int Fun( int now, int last, int n )
{
int max = 0;
int s = 0,i;
int tmp = ST[now]|ST[last];
if ( dp[now][last][n] != -1 ) return dp[now][last][n];
for ( i = 0; i < m; ++i )
{
if ( (ST[now]&(~(1<<i))) != ST[now] ) ++s;
}
if ( n == 1 )
{
dp[now][last][1] = s;
return s;
}
for (i = 0; i < len; ++i )
{
int flag = 1;
int s = 0;
if ( tmp&ST[i] ) continue;
for ( int j = 0; j < m; ++j )
{
if ( map[n-2][j] == 'H' && (ST[i]&(~(1<<j))) != ST[i] )
{
flag = 0;
break;
}
}
if ( flag ) max >?= Fun( last, i, n-1 );
}
max += s;
dp[now][last][n] = max;
return max;
}
bool OK( int a )
{
if ( a<0 || a>= m ) return false;
else return true;
}
int main()
{
int power,ncase;
int max = 0;
scanf( "%d%d", &n, &m );
power = (int)pow( 2, m );
for ( int i = 0; i < m; ++i ) map[0][i] = 'H';
for ( int i = 1; i <= n; ++i )
{
scanf( "%s", map[i] );
}
for ( int i = 0; i < power; ++i )
{
int flag = 0;
for ( int j = 0; j < m; ++j )
{
if ( (i&(~(1<<j))) != i )
{
if ( OK(j-1) && (i&(~(1<<(j-1))))!=i )
{
flag = 1;
break;
}
if ( OK(j-2) && (i&(~(1<<(j-2))))!=i )
{
flag = 1;
break;
}
if ( OK(j+1) && (i&(~(1<<(j+1))))!=i )
{
flag = 1;
break;
}
if ( OK(j+2) && (i&(~(1<<(j+2))))!=i )
{
flag = 1;
break;
}
}
}
if ( flag == 0 )
{
ST[len++] = i;
}
}
for ( int i = 0; i < 60; ++i )
{
for ( int j = 0; j < 60; ++j )
{
for ( int k = 0; k < 101; ++k )
{
dp[i][j][k] = -1;
}
}
}
for ( int i = 0; i < len; ++i )
{
for ( int j = 0; j < len; ++j )
{
int flag = 1;
if ( (ST[i]&ST[j]) ) continue;
for ( int k = 0; k < m; ++k )
{
if ( map[n][k] == 'H' && (ST[i]&(~(1<<k)))!=ST[i] )
{
flag = 0;
break;
}
if ( map[n-1][k] == 'H' && (ST[j]&(~(1<<k)))!=ST[j] )
{
flag = 0;
break;
}
}
if ( flag ) max >?= Fun( i, j, n );
}
}
printf( "%d\n", max );
return 0;
}