快让我静静!!!!TAT
这道题debug了一早上。。差点没把我烦死。。。
要考虑决定状态的因素!!!!
应该还是很中规中矩的状压,由于曼哈顿距离是2,所以每种情况,都要检查前两行是否符合条件。因为i-2行也是决定因素,所以不能忽略i-2行,需要进行记录,可能上一状态中获得同一值有多种前驱状态,但是这些前驱也会决定是否能生成当前行。
恩。。然后其实可以打表先处理出左右没有冲突的情况,貌似只有两百多种的样子,这样就不用结构体了,可以开个三维数组
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#define maxn 1100
int n,m;
int a[110][110];
class node
{
public:
int top,vis;
int pre[maxn],ans[maxn];
void init()
{
top=0,vis=0;
pre[0]=ans[0]=0;
}
void update(int x,int y)
{
pre[top]=x;
ans[top++]=y;
}
int frontpre()
{
if(!top) return -1;
return pre[top-1];
}
int sum()
{
if(!top) return 0;
return ans[top-1];
}
}dp[2][maxn];
bool check(int x,int r,int &ret)
{
int que[12],top=0;
while(x)
{
que[top++]=x&1;
x>>=1;
}
for(int i=0;i<m;i++)
{
if(i<top&&que[i])
{
if(!a[r][i]) return false;
else if(i-2>=0&&que[i-2]) return false;
else ret++;
}
x>>=1;
}
return true;
}
bool comp(int now,int pre)
{
int n[12],p[12];
int nn=0,pp=0;
if(!now||!pre) return true;
while(now)
{
n[nn++]=now&1;
now>>=1;
}
while(pre)
{
p[pp++]=pre&1;
pre>>=1;
}
for(int i=0;i<nn;i++)
{
if(n[i])
{
int j=i-1,k=i+1;
if((j>=0&&j<pp&&p[j])||(k<pp&&k>=0&&p[k])) return false;
}
}
return true;
}
int max(int x,int y){return x>y?x:y;}
void search()
{
int flag=0;
int maxnum=1<<m;
for(int i=0;i<maxnum;i++) dp[1][i].init(),dp[0][i].init();
dp[1][0].vis=1,dp[1][0].update(0,0);
for(int i=0;i<n;i++)
{
flag=i&1;
for(int now=0;now<maxnum;now++)
{
int num=0;
if(!check(now,i,num)) continue;
for(int pre=0;pre<maxnum;pre++)
{
if(!comp(now,pre)) continue;
node tmp=dp[!flag][pre];
int nowsum=0;
if(!tmp.vis) continue;
int k=0;
for(int j=0;j<tmp.top;j++)
{
int sum=tmp.ans[j];
if(now&tmp.pre[j]) continue;
nowsum=max(nowsum,sum+num);
k=1;
}
if(!k) continue;
dp[flag][now].update(pre,nowsum);
// printf("dp[%d][%d]=%d pre-->%d num-->%d\n",i,now,dp[flag][now].sum(),pre,nowsum);
dp[flag][now].vis=1;
}
}
for(int j=0;j<maxnum;j++) dp[!flag][j].init();
}
int ans=0;
for(int i=0;i<maxnum;i++)
if(dp[flag][i].vis) ans=max(ans,dp[flag][i].sum());
cout<<ans<<endl;
}
int main()
{
while(cin>>n>>m)
{
int x;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
}
}
search();
}
return 0;
}