原题链接
代码:
#include <bits/stdc++.h>
#define ll long long
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
template<class T> inline void read(T &x){
x=0; register char c=getchar(); register bool f=0;
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c))x=x*10+c-'0',c=getchar(); if(f)x=-x;
}
using namespace std;
int a[105];
int num[105],st[105][1025];
int dp[101][1025][1025];
int vis[105][1025];
int main()
{
int n,m;
char s[20];
scanf("%d %d",&n,&m);
int k=1<<m;//状态总数
for(int i=1;i<=n;i++)
{
scanf("%s",s);
for(int j=0;j<m;j++)
{
if(s[j]=='P')
{
a[i]+=(1<<j);}
}
}
for(int i=1;i<=n;i++)//initialization
{
for(int j=0;j<k;j++)
{
if((j|a[i])!=a[i])continue;
if((j<<1)&j)continue;
if((j<<2)&j)continue;
st[i][num[i]]=j;
for(int e=0;e<m;e++){
if((j>>e)&1){
vis[i][num[i]]++;
}
}
num[i]++;
}
}
int ans=-99999999;
for(int i=0;i<num[1];i++){
//预处理第一行数据
dp[1][i][0]=vis[1][i];
ans=max(ans,dp[1][i][0]);
}
for(int i=0;i<num[2];i++){
//预处理第二行
for(int j=0;j<num[1];j++){
if(st[2][i]&st[1][j])continue;
dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+vis[2][i]);
ans=max(ans,dp[2][i][j]);
}
}
for(int i=3;i<=n;i++){
//循环行数
for(int j=0;j<num[i];j++){
//循环该行的合法状态
for(int s1=0;s1<num[i-1];s1++){
//循环上一行的合法状态
for(int s2=0;s2<num[i-2];s2++){
//循环上两行的合法状态
if(st[i-1][s1]&st[i-2][s2])continue;
if(st[i][j]&st[i-1][s1])continue;
if(st[i][j]&st[i-2][s2])continue;
dp[i][j][s1]=max(dp[i][j][s1],dp[i-1][s1][s2]+vis[i][j]);
ans=max(ans,dp[i][j][s1]);
}
}
}
//cout<<ans<<endl;
}
printf("%d\n",ans);
return 0;
}