这个题主要记住前一行和上上行的状态,前一行相邻地方不能为1,上上行相同位置不能为1,三维dp,用i记录行 用j记录这一行状态,用k记录上一行的状态,
<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
int max(int a,int b)
{
return a>b?a:b;
}
int dp[110][200][200];
int main()
{
int n,m,i,j,z,h,w,o,q,p,k,a[110][100],t[200];
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=2;i<=n+1;i++)//这里从1开始也行
for(j=0;j<m;j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
int q=0;
for(i=0;i<1<<m;i++)
{
if((i&(i*4))==0)
t[q++]=i;
}
for(i=2;i<=n+1;i=i+1)
{
for(j=0;j<q;j++)
{
z=0;
h=1;
for(k=0;k<m;k++)//这一点是为了判断这种状态是否可一在这一行(因为有的一行很多地方为0,如果这种状态这个地方是1,这中状态在这行就不可用了
{
int c;
c=1<<k;
if((t[j]&c))
{
if(a[i][k]==0)
h=0;
else
z++;
}
}
if(h==0)
continue;//前面是为了判断这一种状态是否可以在这一行
for(k=0;k<q;k++)
{
if((t[j]&(t[k]<<1))==0&&((t[j]<<1)&t[k])==0)//判断这一行与前一行是否冲突
for(w=0;w<q;w++)
{
if((t[w]&t[j])==0)//判断这一行与上上行是否冲突
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][w]+z);
}
}
}
}
k=0;
for(i=0;i<q;i++)//扫描第n+1行那种状态最大
{
for(j=0;j<q;j++)
{
k=max(k,dp[n+1][i][j]);
}
}
printf("%d\n",k);
}
return 0;
}