狀態壓縮入門(附經典題目和題解)
阿新 • • 發佈:2018-12-15
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,ans;
char iin;
int f[(1<<10)][(1<<10)][3],a[150],sum[(1<<10)];
int get(int s)
{
int cnt=0;
while(s)
{
if(s&1) cnt++;
s >>=1;
}
return cnt;
}
int Max(int a,int b)
{
if(a>=b) return a;
return b;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>iin;;
a[i]<<=1;
a[i]+=(iin==' H'?1:0);
}
for(int i=0;i<(1<<m);i++)
sum[i]=get(i);
for(int i=0;i<(1<<m);i++)
for(int j=0;j<(1<<m);j++)
if(!(i&j || i&(i<<1) || i&(i<<2) || j&(j<<1) || j&(j<<2) || i&a[0] || j&a[1]))
f[i][j][ 1]=sum[i]+sum[j];
for(int k=2;k<n;k++)
for(int i=0;i<(1<<m);i++)
{
if(i&a[k-1] || i&(i<<1) || i&(i<<2)) continue;
for(int j=0;j<(1<<m);j++)
{
if(i&j || j&a[k] || j&(j<<1) || j&(j<<2)) continue;
for(int l=0;l<(1<<m);l++)
{
if(l&i || l&j || l&a[k-2] || l&(l<<1) || l&(l<<2)) continue;
{
f[i][j][k%3]=Max(f[i][j][k%3],f[l][i][(k-1)%3]+sum[j]);
}
}
}
}
for(int i=0;i<(1<<m);i++)
for(int j=0;j<(1<<m);j++)
ans=Max(ans,f[i][j][(n-1)%3]);
printf("%d",ans);
return 0