继续来上状态压缩的dp,发现自己真的是上道了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> using namespace std; const int maxn=100+5; const int maxm=10+5; int n,m,tot; int state[170],stanum[170]; int in[maxn]; bool flg[maxm]; void dfs(int cur,int st,int count) { if(cur==m) { state[tot]=st; stanum[tot++]=count; return; } flg[cur+1]=0; dfs(cur+1,st<<1,count); if(cur<1) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } else { if(flg[cur-1]==0) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } } } void init() { tot=0; dfs(0,0,0); // cout<<tot<<endl; } inline int max(int a,int b) { return a<b?b:a; } void data_in() { int tmp; for(int i=1;i<=n;i++) { in[i]=0; for(int j=1;j<=m;j++) { scanf("%d",&tmp); tmp=1-tmp; in[i]<<=1; in[i]|=tmp; } } } int dp[2][170][170]; void DP() { int ans=0; memset(dp,-1,sizeof(dp)); for(int i=0;i<tot;i++) { if(in[1]&state[i]) continue; dp[1][i][0]=stanum[i]; ans=max(ans,dp[1][i][0]); } int now=1; for(int i=2;i<=n;i++) { now^=1; for(int j=0;j<tot;j++) { if(in[i]&state[j]) continue; else for(int k=0;k<tot;k++) { if(state[j]&(state[k]<<1)) continue; else if(state[j]&(state[k]>>1)) continue; else for(int p=0;p<tot;p++) { if(state[j]&state[p]) continue; else if(dp[now^1][k][p]==-1) continue; else { dp[now][j][k]=max(dp[now][j][k],dp[now^1][k][p]+stanum[j]); ans=max(ans,dp[now][j][k]); } } } } } printf("%d\n",ans); } int main() { while(~scanf("%d %d",&n,&m)) { init(); data_in(); DP(); } return 0; }