题目链接:
https://vjudge.net/contest/159644#problem/H
题意:
注意 是曼哈顿距离恰好是2,恰好!!!
题解:
与poj1185差不多的…
滚动数组,否则MLE,是我MLE了…
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;
ll dp[2][1005][1005];
int num[1005],cur[105];
int n,m,cnt;
int sta[1005];
int getnum(int x){
int res = 0;
while(x){
if(x & 1) res++;
x >>= 1;
}
return res;
}
void init(){
cnt = 0;
for(int i=0; i<=(1<<10); i++){
if(!(i & (i<<2))){
sta[cnt] = i;
num[cnt] = getnum(i);
cnt++;
}
}
}
int main(){
init();
while(cin>>n>>m){
MS(cur);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++){
int x; cin >> x;
if(x == 1) cur[i] += (1<<j);
}
memset(dp,-1,sizeof(dp));
int now=0,pre=1;
for(int i=0; i<cnt; i++){
if(!(sta[i]&(~cur[0])))
dp[now][i][0] = num[i];
}
for(int i=1; i<n; i++){
swap(now,pre);
for(int j=0; j<cnt; j++){
if(sta[j]&(~cur[i])) continue;
for(int k=0; k<cnt; k++){
if(sta[k]&(~cur[i-1])) continue;
if(((sta[j]<<1)&sta[k]) || ((sta[j]>>1)&sta[k])) continue;
for(int x=0; x<cnt; x++){
if(i>=2 && (sta[x]&(~cur[i-2]))) continue;
if(sta[j]&sta[x]) continue;
if(dp[pre][k][x] == -1) continue;
dp[now][j][k] = max(dp[now][j][k],dp[pre][k][x]+num[j]);
}
}
}
}
ll ans = 0;
for(int i=0; i<cnt; i++)
for(int j=0; j<cnt; j++)
ans = max(ans,dp[now][i][j]);
cout << ans << endl;
}
return 0;
}