标签:
/*第一种方法*/ #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mn=977147; int i; struct na{ int x,z; na(int xx,int zz):x(xx),z(zz){} }; int n,m,x,y,z,a[21],k,en,u=0,p1,p2; bool map[21][21]; int f[2][mn+1],ans; int v[2][mn+1]; int re[21][21]; queue <na> q; inline int gx(int x,int q1,int q2){k=0;for (register int i=m+1;i;i--) k=k*3+(i==x?q1:(i==x+1?q2:a[i]));return k;} inline void up(int x,int z,int lj,bool la){ if (la) lj+=re[x/m+1][x%m+1]; x++; k=x%2; 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,0,sizeof(map));memset(v,0,sizeof(v));memset(re,0,sizeof(re));memset(f,0,sizeof(f)); for (i=1;i<=m;i++) for (j=1;j<=n;j++) map[i][j+2]=1; for (i=1;i<=n;i++) for (j=1;j<=m;j++) scanf("%d",&re[i+2][j]); n+=4; m+=2; en=n*m-1; for (i=1;i<=m;i++) map[i][1]=map[i][n]=1; for (i=1;i<=n;i++) map[m][i]=1; map[1][2]=1;map[m-2][n-1]=1; if (n==1&&m==1){ printf("%d\n",re[1][1]); continue; } f[0][0]=0;v[0][0]=1; q.push(na(0,0)); while(!q.empty()){ na no=q.front();q.pop(); int an=f[no.x%2][no.z]; if(no.x%m==0) no.z*=3; x=no.x%m+1;y=no.x/m+1; for (i=1;i<=m+1;i++) a[i]=0; for (i=1,j=no.z;j;i++,j/=3) a[i]=j%3; if (!map[x][y])up(no.x,gx(x,0,0),an,0);else if (a[x]==1&&a[x+1]==2){ if (no.x==en) ans=max(ans,an); }else if (a[x]==2&&a[x+1]==1) up(no.x,gx(x,0,0),an,1);else if (a[x]==0&&a[x+1]==0){ if (no.x!=en&&no.x!=1) up(no.x,gx(x,0,0),an,0); if (map[x][y+1]&&map[x+1][y]) up(no.x,gx(x,1,2),an,1); }else if (a[x]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x+1]),an,1); if (map[x][y+1]) up(no.x,gx(x,a[x+1],0),an,1); }else if (a[x+1]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x]),an,1); if (map[x][y+1]) up(no.x,gx(x,a[x],0),an,1); }else if (a[x]==a[x+1]){ p1=p2=0; if (a[x]==1) for (j=0,i=x+2;i<=m;i++){ if (a[i]==1) j--; if (a[i]==2) j++; if (j>0&&!p1) p1=i,j--; if (j>0&&p1){p2=i;break;} }else for (j=0,i=x-1;i;i--){ if (a[i]==1) j++; if (a[i]==2) j--; if (j>0&&!p2) p2=i,j--; if (j>0&&p2){p1=i;break;} } a[p1]=1;a[p2]=2;up(no.x,gx(x,0,0),an,1); } } 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[21],k,en,u=0,p1,p2; bool map[21][21]; int f[2][1277148],ans; int v[2][1277148]; int re[21][21]; queue <na> q; inline int gx(int x,int q1,int q2){k=0;for (register int i=m+1;i;i--) k=k*3+(i==x?q1:(i==x+1?q2:a[i]));return k;} inline void up(int x,int z,int lj,bool la){ if (la) lj+=re[x/m+1][x%m+1]; x++; k=x%2; 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=0; memset(map,0,sizeof(map));memset(v,0,sizeof(v));memset(f,0,sizeof(f)); en=n*m-1; for (i=1;i<=m;i++) for (j=1;j<=n;j++) map[i][j]=1; for (i=1;i<=n;i++) for (j=1;j<=m;j++) scanf("%d",&re[i][j]); if (n==1&&m==1){ printf("Case %d: %d\n",u,re[1][1]); continue; } f[0][1]=0; v[0][0]=1; q.push(na(0,1)); while(!q.empty()){ na no=q.front();q.pop(); int an=f[no.x%2][no.z]; if (no.x%m==0) no.z*=3; x=no.x%m+1;y=no.x/m+1; for (i=1;i<=m+1;i++) a[i]=0; for (i=1,j=no.z;j;i++,j/=3) a[i]=j%3; if (no.x==en){ k=0; for (i=1;i<=m+1;i++) k+=a[i]!=0; if (k==1&&(a[m]==1||a[m+1]==1)&&an+re[n][m]>ans) ans=an+re[n][m]; continue; } if (a[x]==2&&a[x+1]==1){ up(no.x,gx(x,0,0),an,1); }else if (a[x]==0&&a[x+1]==0){ up(no.x,gx(x,0,0),an,0); if (map[x][y+1]&&map[x+1][y]) up(no.x,gx(x,1,2),an,1); }else if (a[x]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x+1]),an,1); if (map[x][y+1]) up(no.x,gx(x,a[x+1],0),an,1); }else if (a[x+1]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x]),an,1); if (map[x][y+1]) up(no.x,gx(x,a[x],0),an,1); }else if (a[x]==1&&a[x+1]==1){ p1=p2=0; for (j=0,i=x+2;i<=m+1;i++){ if (a[i]==1) j--; if (a[i]==2) j++; if (j>0&&!p1) p1=i,j--; if (j>0&&p1){p2=i;break;} } a[p1]=1;a[p2]=2; up(no.x,gx(x,0,0),an,1); }else if (a[x]==2&&a[x+1]==2){ p1=p2=0; for (j=0,i=x-1;i;i--){ if (a[i]==1) j++; if (a[i]==2) j--; if (j>0&&!p2) p2=i,j--; if (j>0&&p2){p1=i;break;} } a[p1]=1;a[p2]=2;up(no.x,gx(x,0,0),an,1); } } printf("Case %d: %d\n",u,ans); } }
标签:
原文地址:http://www.cnblogs.com/Enceladus/p/5137176.html