【NOIP模拟】立方体

Description

【NOIP模拟】立方体_第1张图片

Solution

刚看到这题,还以为是连边然后做spfa,然后答题后发现这样很麻烦。
然后在打暴搜的时候,发现在搜索的过程中状态数很少,然后暴搜的速度很快。
但是刚开始我用f[x][y]来记忆化到点(x,y)的最短距离,后来结果出来了只有40分,TAT。
才发现到达一个地方可能有多种不同的状态,所有还要多存几维,用f[x][y][k][l][t]表示到(x,y)这个点,前面为k下面为l,右面为t,存到这个状态的最小和,然后直接暴搜就可以了。

Code

#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);
}

你可能感兴趣的:(noip,记忆化搜索,暴搜)