很经典的一道状压DP,慢慢试着学习这列状压DP......炮兵阵地,可以DFS暴力搜索,可是不会......
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int ma[105],st[65],sum[105];
int dp[105][65][65];
char x[15];
int main()
{
int N,M;
while(scanf("%d%d",&N,&M)!=EOF)
{
memset(ma,0,sizeof(ma));
memset(st,0,sizeof(st));
memset(dp,-1,sizeof(dp));
memset(sum,0,sizeof(sum));
for(int i=0;i<N;i++)
{
scanf("%s",x);
for(int j=0;j<M;j++)
{
if(x[j]=='H')
ma[i]+=(1<<j);
}
}
int num=0;
for(int i=0;i<(1<<M);i++)
{
if((i&(i<<1))||(i&(i<<2))) continue;
int k=i;
while(k)
{
sum[num]+=(k&1);
k=k>>1;
}
st[num++]=i;
}
for(int i=0;i<num;i++)
{
if(st[i]&ma[0]) continue;
dp[0][i][0]=sum[i];
}
for(int r=1;r<N;r++)
{
for(int i=0;i<num;i++)
{
if(ma[r]&st[i]) continue;
for(int j=0;j<num;j++)
{
if(st[i]&st[j]) continue;
for(int e=0;e<num;e++)
{
if(st[i]&st[e]) continue;
if(st[j]&st[e]) continue;
if(dp[r-1][j][e]==-1) continue;
dp[r][i][j]=max(dp[r][i][j],dp[r-1][j][e]+sum[i]);
}
}
}
}
int ans=0;
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
ans=max(ans,dp[N-1][i][j]);
}
}
printf("%d\n",ans);
}
return 0;
}