插头DP.细节很多.
AC code:
#include <cstdio>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
const int N=101;
const int M=11;
int n,m,ans=-(1<<28);
int bt[M];
int w[N][M];
map<int,int> f[N][M];
map<int,bool> vis[N][M];
struct State{
int i,j,S;
State(int i,int j,int S):i(i),j(j),S(S) {}
};
void read(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
scanf("%d",&w[i][j]);
}
for(int i=1;i<=m+1;i++) bt[i]=(m-i+1)<<1;
}
int get(int S,int k){
return ((S&(1<<bt[k]))+(S&(1<<(bt[k]+1))))>>bt[k];
}
int modify(int S,int k,int s){
return S^(get(S,k)<<bt[k])^(s<<bt[k]);
}
void BFS(){
queue<State> Q;
Q.push(State(0,m,0));
while(!Q.empty()){
State x=Q.front();
Q.pop();
int i=x.i,j=x.j+1,S=x.S;
if(j==m+1){
i++;j=1;
S>>=2;
if(i==n+1) break;
}
int c1=get(S,j),c2=get(S,j+1);
if((!c1)&&(!c2)){
if(!vis[i][j][S]){
vis[i][j][S]=1;
Q.push(State(i,j,S));
f[i][j][S]=f[x.i][x.j][x.S];
}
else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]);
}
if(c1&&(!c2)&&i!=n){
if(!vis[i][j][S]){
vis[i][j][S]=1;
Q.push(State(i,j,S));
f[i][j][S]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]+w[i][j]);
}
if((!c1)&&c2&&j!=m){
if(!vis[i][j][S]){
vis[i][j][S]=1;
Q.push(State(i,j,S));
f[i][j][S]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]+w[i][j]);
}
if((!c1)&&c2&&i!=n){
int SS=modify(modify(S,j,c2),j+1,c1);
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if(c1&&(!c2)&&j!=m){
int SS=modify(modify(S,j,c2),j+1,c1);
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if((!c1)&&(!c2)&&i!=n&&j!=m){
int SS=modify(modify(S,j,1),j+1,2);
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if(c1==2&&c2==1){
int SS=modify(modify(S,j,0),j+1,0);
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if(c1==1&&c2==1){
int cnt=0,SS=modify(modify(S,j,0),j+1,0);
for(int k=j+2;k<=m+1;k++){
if(get(SS,k)==2) cnt++;
else if(get(SS,k)==1) cnt--;
if(cnt==1){
SS=modify(SS,k,1);
break;
}
}
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if(c1==2&&c2==2){
int cnt=0,SS=modify(modify(S,j,0),j+1,0);
for(int k=j-1;k>=1;k--){
if(get(SS,k)==1) cnt++;
else if(get(SS,k)==2) cnt--;
if(cnt==1){
SS=modify(SS,k,2);
break;
}
}
if(!vis[i][j][SS]){
vis[i][j][SS]=1;
Q.push(State(i,j,SS));
f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];
}
else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);
}
if(c1==1&&c2==2){
int cnt=0;
for(int k=1;k<=m+1;k++){
if(get(S,k)==1) cnt++;
}
if(cnt==1) ans=max(ans,f[x.i][x.j][x.S]+w[i][j]);
}
}
printf("%d",ans);
}
int main(){
read();
BFS();
return 0;
}