题意:如题
思路:由于相同行列的相邻两个格子都不能放所以用二进制模拟
由于相邻两个的状态比较少
所以有效的状可以打表出来优化时间
ACcode:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char maze[110][20];
long long vis[110];
long long dp[110][70][70];
long long num[70];
long long Count[70];
long long n,m,cnt;
long long ans;
long long Flag(long long x){
if( (x&(x<<1)) !=0 || (x&(x<<2)) != 0 ) return 0;
return 1;
}
long long Cnt(long long x){
long long res = 0;
for(long long i=0;i<12;i++) if( (x &(1<<i)) !=0 ) res++;
return res;
}
int main(){
while(scanf("%lld%lld",&n,&m)!=EOF){
if(n == 0 && m == 0) break;
long long mark = (1<<m)-1;
cnt = 0;
for(long long i=0;i<=mark;i++){
if(Flag(i) == 1){
num[++cnt]=i;
Count[cnt]=Cnt(i);
}
}
memset(dp,0,sizeof dp);
memset(vis,0,sizeof vis);
for(long long i=1;i<=n;i++){
scanf("%s",maze[i]);
for(long long j=0;j<m;j++){
if(maze[i][j] == 'H') vis[i]|=(1<<j);
}
}
ans = 0;
for(long long i=1;i<=n;i++){
for(long long j=1;j<=cnt;j++){
if( (vis[i]&num[j]) == 0){
for(long long k=1;k<=cnt;k++){
if((num[j]&num[k]) == 0 ){
for(long long x=1;x<=cnt;x++){
if( (num[j]&num[x]) == 0 && (num[k]&num[x]) == 0 ){ //当上个状态 及上个状态的上个状态均符合题意
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][x]+Count[j]);
ans = max(ans,dp[i][j][k]);
}
}
}
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}