题解:
这题应该不是很难
很容易就看出状压
d
p
dp
dp
这一行的状态与上两行有关,所以用
3
n
3^n
3n的
d
p
dp
dp表示上一行和上上行的状态,然后暴力转移。
注意每一行之内也是有制约的。
C
o
d
e
:
Code:
Code:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define INF 1e10
#define N 105
#define ll long long
using namespace std;
int n,m,len1,len2,len3,last[N],last1[N],now[N],num[N],dp[N][N],temp[N][N];
char Map[N][N];
void dfs(int id,int k,int p,int sum)
{
if(k>=m){now[++len1]=p;num[len1]=sum;return;}
if(Map[id][k]=='P')dfs(id,k+3,p|(1<<k),sum+1);
dfs(id,k+1,p,sum);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%s",Map[i]);
last[1]=last1[1]=temp[1][1]=0;
len2=len3=1;
for(int k=1;k<=n;k++)
{
memset(now,0,sizeof(now));
len1=0;
dfs(k,0,0,0);
memset(dp,0,sizeof(dp));
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)
for(int t=1;t<=len3;t++)
{
if(now[i]&last[j])continue;
if(now[i]&last1[t])continue;
if(dp[i][j]<temp[j][t]+num[i])dp[i][j]=temp[j][t]+num[i];
}
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)temp[i][j]=dp[i][j];
for(int i=1;i<=len2;i++)last1[i]=last[i];len3=len2;
for(int i=1;i<=len1;i++)last[i]=now[i];len2=len1;
}
int sum=0;
for(int i=1;i<=len2;i++)
for(int j=1;j<=len3;j++)
if(temp[i][j]>sum)sum=temp[i][j];
printf("%d\n",sum);
return 0;
}