Now they
comes to the magical world and Lilish ask Resty to play with her.
The
game is following :
Now the world is divided into a m * n grids by Lilith,
and Lilith gives each grid a score.
So we can use a matrix to describe
it.
You should come from cell(0, 0) to cell(m-1, n-1) (Up-Left to Down-Right)
and try to colloct as more score as possible.
According to Lilish's rule, you
can't arrive at each cell more than once.
Resty knows that Lilish will be
easy to find the max score, and he doesn't want to lose the game.
So he want
to find the game plan to reach the max score.
Your task is to calculate
the max score that Lilish will find, the map is so small so it shouldn't be
difficult for you, right?
testdata.
Process to the END OF DATA.
For each test data :
the first
live give m and n. (1<=m<=8, 1<=n<=9)
following m lines, each
contain n number to give you the m*n matrix.
each number in the matrix is
between -2000 and 2000
data
Don't print any empty line to the output
两种方法,第一是上下加两行,加两列,加障碍,使题目变成简单的回路,而不是单路。
/*第一种方法*/
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mn=;
int i;
struct na{
int x,z;
na(int xx,int zz):x(xx),z(zz){}
};
int n,m,x,y,z,a[],k,en,u=,p1,p2;
bool map[][];
int f[][mn+],ans;
int v[][mn+];
int re[][];
queue <na> q;
inline int gx(int x,int q1,int q2){k=;for (register int i=m+;i;i--) k=k*+(i==x?q1:(i==x+?q2:a[i]));return k;}
inline void up(int x,int z,int lj,bool la){
if (la) lj+=re[x/m+][x%m+];
x++;
k=x%;
if (v[k][z]!=x) v[k][z]=x,f[k][z]=-1e9,q.push(na(x,z));
f[k][z]=max(f[k][z],lj);
}
int main(){
//freopen("a.in","r",stdin);
register int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
u++;
printf("Case %d: ",u);
ans=-1e9;
memset(map,,sizeof(map));memset(v,,sizeof(v));memset(re,,sizeof(re));memset(f,,sizeof(f));
for (i=;i<=m;i++)
for (j=;j<=n;j++)
map[i][j+]=;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
scanf("%d",&re[i+][j]);
n+=;
m+=;
en=n*m-;
for (i=;i<=m;i++) map[i][]=map[i][n]=;
for (i=;i<=n;i++) map[m][i]=;
map[][]=;map[m-][n-]=;
if (n==&&m==){
printf("%d\n",re[][]);
continue;
}
f[][]=;v[][]=;
q.push(na(,));
while(!q.empty()){
na no=q.front();q.pop();
int an=f[no.x%][no.z];
if(no.x%m==) no.z*=;
x=no.x%m+;y=no.x/m+;
for (i=;i<=m+;i++) a[i]=;
for (i=,j=no.z;j;i++,j/=) a[i]=j%;
if (!map[x][y])up(no.x,gx(x,,),an,);else
if (a[x]==&&a[x+]==){
if (no.x==en) ans=max(ans,an);
}else if (a[x]==&&a[x+]==) up(no.x,gx(x,,),an,);else
if (a[x]==&&a[x+]==){
if (no.x!=en&&no.x!=) up(no.x,gx(x,,),an,);
if (map[x][y+]&&map[x+][y]) up(no.x,gx(x,,),an,);
}else if (a[x]==){
if (map[x+][y]) up(no.x,gx(x,,a[x+]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x+],),an,);
}else if (a[x+]==){
if (map[x+][y]) up(no.x,gx(x,,a[x]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x],),an,);
}else if (a[x]==a[x+]){
p1=p2=;
if (a[x]==)
for (j=,i=x+;i<=m;i++){
if (a[i]==) j--;
if (a[i]==) j++;
if (j>&&!p1) p1=i,j--;
if (j>&&p1){p2=i;break;}
}else
for (j=,i=x-;i;i--){
if (a[i]==) j++;
if (a[i]==) j--;
if (j>&&!p2) p2=i,j--;
if (j>&&p2){p1=i;break;}
}
a[p1]=;a[p2]=;up(no.x,gx(x,,),an,);
}
}
printf("%d\n",ans);
}
}
/*第二种方法*/
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int i;
struct na{
int x,z;
na(int xx,int zz):x(xx),z(zz){}
};
int n,m,x,y,z,a[],k,en,u=,p1,p2;
bool map[][];
int f[][],ans;
int v[][];
int re[][];
queue <na> q;
inline int gx(int x,int q1,int q2){k=;for (register int i=m+;i;i--) k=k*+(i==x?q1:(i==x+?q2:a[i]));return k;}
inline void up(int x,int z,int lj,bool la){
if (la) lj+=re[x/m+][x%m+];
x++;
k=x%;
if (v[k][z]!=x) v[k][z]=x,f[k][z]=lj,q.push(na(x,z));
if (lj>f[k][z]) f[k][z]=lj;
}
int main(){
register int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
u++;
ans=;
memset(map,,sizeof(map));memset(v,,sizeof(v));memset(f,,sizeof(f));
en=n*m-;
for (i=;i<=m;i++)
for (j=;j<=n;j++)
map[i][j]=;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
scanf("%d",&re[i][j]);
if (n==&&m==){
printf("Case %d: %d\n",u,re[][]);
continue;
}
f[][]=;
v[][]=;
q.push(na(,));
while(!q.empty()){
na no=q.front();q.pop();
int an=f[no.x%][no.z];
if (no.x%m==) no.z*=;
x=no.x%m+;y=no.x/m+;
for (i=;i<=m+;i++) a[i]=;
for (i=,j=no.z;j;i++,j/=) a[i]=j%;
if (no.x==en){
k=;
for (i=;i<=m+;i++) k+=a[i]!=;
if (k==&&(a[m]==||a[m+]==)&&an+re[n][m]>ans) ans=an+re[n][m];
continue;
}
if (a[x]==&&a[x+]==){
up(no.x,gx(x,,),an,);
}else if (a[x]==&&a[x+]==){
up(no.x,gx(x,,),an,);
if (map[x][y+]&&map[x+][y])
up(no.x,gx(x,,),an,);
}else if (a[x]==){
if (map[x+][y]) up(no.x,gx(x,,a[x+]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x+],),an,);
}else if (a[x+]==){
if (map[x+][y]) up(no.x,gx(x,,a[x]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x],),an,);
}else if (a[x]==&&a[x+]==){
p1=p2=;
for (j=,i=x+;i<=m+;i++){
if (a[i]==) j--;
if (a[i]==) j++;
if (j>&&!p1) p1=i,j--;
if (j>&&p1){p2=i;break;}
}
a[p1]=;a[p2]=;
up(no.x,gx(x,,),an,);
}else if (a[x]==&&a[x+]==){
p1=p2=;
for (j=,i=x-;i;i--){
if (a[i]==) j++;
if (a[i]==) j--;
if (j>&&!p2) p2=i,j--;
if (j>&&p2){p1=i;break;}
}
a[p1]=;a[p2]=;up(no.x,gx(x,,),an,);
}
}
printf("Case %d: %d\n",u,ans);
}
}