刚看到这题,还以为是连边然后做spfa,然后答题后发现这样很麻烦。
然后在打暴搜的时候,发现在搜索的过程中状态数很少,然后暴搜的速度很快。
但是刚开始我用f[x][y]来记忆化到点(x,y)的最短距离,后来结果出来了只有40分,TAT。
才发现到达一个地方可能有多种不同的状态,所有还要多存几维,用f[x][y][k][l][t]表示到(x,y)这个点,前面为k下面为l,右面为t,存到这个状态的最小和,然后直接暴搜就可以了。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define rep(i,a) for(i=first[a];i;i=next[i])
using namespace std;
const int maxn=80;
int fi1,fi2,en1,en2;
int a[7],f[maxn][maxn][10][10][10];
char s[5],st[5];
int fang[4][2]={1,0,0,1,-1,0,0,-1};
int d[7]={0,2,1,5,6,3,4};
int i,j,k,l,t,n,m,ans;
void dfs(int x,int y,int z,int q,int xi,int yo){
int i,j,k,xx,yy;
if(x<1||x>8||y<1||y>8)return;
if(z>=ans)return;
if(f[x][y][q][xi][yo]<=z)return;
f[x][y][q][xi][yo]=z;
if(x==en1&&y==en2){
ans=min(ans,f[x][y][q][xi][yo]);
return;
}
fo(k,0,3){
xx=fang[k][0]+x,yy=fang[k][1]+y;
if(k==0){
dfs(xx,yy,z+a[q],d[xi],q,yo);
}
else if(k==1){
dfs(xx,yy,z+a[yo],q,yo,d[xi]);
}
else if(k==2){
dfs(xx,yy,z+a[d[q]],xi,d[q],yo);
}
else{
dfs(xx,yy,z+a[d[yo]],q,d[yo],xi);
}
}
}
int main(){
scanf("%s%s%d%d%d%d%d%d",s,st,&a[1],&a[2],&a[3],&a[4],&a[5],&a[6]);
fi1=s[1]-'1'+1;fi2=s[0]-'a'+1;
en1=st[1]-'1'+1;en2=st[0]-'a'+1;
fi1=8-fi1+1;en1=8-en1+1;
memset(f,127,sizeof(f));ans=0x7fffffff;
dfs(fi1,fi2,a[5],1,5,4);
printf("%d\n",ans);
}