简单状压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; }
时间: 2024-10-08 20:13:54