1. 程式人生 > >狀態壓縮入門(附經典題目和題解)

狀態壓縮入門(附經典題目和題解)

#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