状态压缩dp
这方面是菜比
看别人写的
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int map[110];
int dp[110][65][65];
int s[65],sum[65],cnt;
int getNum(int x)
{
int sum=0;
while(x)
{
sum++;
x&=(x-1);
}
return sum;
}
bool ok(int x)
{
if(x&(x<<1))
return 0;
if(x&(x<<2))
return 0;
return 1;
}
void init()
{
memset(map,0,sizeof(map));
memset(dp,-1,sizeof(dp));
cnt=0;
for(int i=0;i<(1<<m);i++)
if(ok(i))
{
s[cnt]=i;
sum[cnt]=getNum(i);
cnt++;
}
}
int main()
{
while(cin>>n>>m)
{
init();
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
char tmp;
cin>>tmp;
if(tmp=='H')
map[i]|=(1<<j);
}
for(int i=0;i<cnt;i++)
if((map[0]&s[i])==0)
dp[0][i][0]=sum[i];
for(int i=1;i<n;i++)
{
for(int j=0;j<cnt;j++)
{
if((map[i]&s[j]))continue;
for(int k=0;k<cnt;k++)
{
if(s[j]&s[k])continue;
for(int p=0;p<cnt;p++)
{
if(s[p]&s[k])continue;
if(s[p]&s[j])continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+sum[j]);
}
}
}
}
int ans=0;
for(int i=0;i<cnt;i++)
for(int j=0;j<cnt;j++)
ans=max(ans,dp[n-1][i][j]);
cout<<ans<<endl;
}
return 0;
}