题意
中文题目,不解释
题解
类似于POJ3254。依然是那几个流程。首先初始化,得到每一行可能的状态集合。然后读取地图,初始化DP数组。DP[i][j][k]代表当前为i层,当前状态为k上一层状态为j。dp[i][k][j]=max(dp[i][k][j],dp[i-1][s][k]+num[j])(K代表第I-1层状态,J代表第I层状态,S代表第I-2层状态)
代码
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int staNum;
int status[110];
int dp[110][110][110];
int cnt[110];
int num[110];
bool good(int x){
if(x&x<<1)
return false;
if(x&x<<2)
return false;
return true;
}
void init(){
staNum=0;
int mx=1<<m;
for(int i=0;i<mx;i++){
if(good(i))
status[++staNum]=i;
}
}
bool fit(int x,int k){
if(x&cnt[k]){
return false;
}
return true;
}
int cou(int x){
int ans=0;
while(x>0){
if(x%2==1){
ans++;
}
x=x>>1;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
memset(cnt,0,sizeof(cnt));
memset(dp,-1,sizeof(dp));
memset(status,0,sizeof(status));
memset(num,0,sizeof(num));
init();
for(int i=1;i<=n;i++){
getchar();
for(int j=1;j<=m;j++){
char ch;
scanf("%c",&ch);
if(ch=='H'){
cnt[i]+=1<<(m-j);
}
}
}
for(int i=1;i<=staNum;i++){
num[i]=cou(status[i]);
if(fit(status[i],1)){
dp[1][1][i]=num[i];
}
}
for(int i=2;i<=n;i++){
for(int j=1;j<=staNum;j++){
if(!fit(status[j],i)){
continue;
}
for(int k=1;k<=staNum;k++){
if(status[j]&status[k])
continue;
for(int s=1;s<=staNum;s++){
if(status[j]&status[s])
continue;
if(dp[i-1][s][k]==-1)
continue;
dp[i][k][j]=max(dp[i][k][j],dp[i-1][s][k]+num[j]);
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=staNum;j++){
for(int k=1;k<=staNum;k++){
ans=max(ans,dp[i][j][k]);
}
}
}
printf("%d\n",ans);
}
return 0;
}