简单状压DP,忘 了初始化,忘 了&和==的优先级,坑了我十几个WA。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[110][222][222];
int row[110];
int status[1<<10];
int counts[1<<10];
int getNum(int s){
int ret=0;
while(s){
if(s&1) ret++;
s>>=1;
}
return ret;
}
int main(){
int n,m,t,cnt;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++){
row[i]=0;
for(int j=0;j<m;j++){
scanf("%d",&t);
if(t==0) row[i]<<=1;
else row[i]=(row[i]<<1)|1;
}
}
cnt=0;
for(int i=0;i<(1<<m);i++){
if((i<<2)&i||(i>>2)&i)continue;
status[cnt++]=i;
counts[cnt-1]=getNum(i);
}
memset(dp,0,sizeof(dp));
int ans=0;
for(int i=1;i<=n;i++){
if(i==1){
for(int j=0;j<cnt;j++){
if((status[j]&row[1])==status[j])
dp[i][j][0]=counts[j];
}
continue;
}
for(int k=0;k<cnt;k++){
if((status[k]&row[i])!=status[k]) continue;
for(int j=0;j<cnt;j++){
if(status[k]&status[j]) continue;
for(int p=0;p<cnt;p++){
if((status[p]&(status[j]>>1))||(status[p]&(status[j]<<1))) continue;
if((status[k]&(status[p]>>1))||(status[k]&(status[p]<<1))) continue;
dp[i][k][p]=max(dp[i][k][p],dp[i-1][p][j]+counts[k]);
}
}
}
}
ans=0;
for(int i=0;i<cnt;i++){
for(int j=0;j<cnt;j++){
ans=max(ans,dp[n][i][j]);
}
}
printf("%d\n",ans);
}
return 0;
}