题目链接
题目分析:
-
典型的多维BFS/DFS搜索题,考虑状态表示为
[x][y][t][f1][f2]
,表示坐标(x,y)
的点在t
时刻,两种卷轴的使用情况为f1,f2(为1表示未使用)
能否到达终点,这里注意点下一时刻可能是停在原地的,所以枚举方向为5个,临时卷轴比较好处理,直接有f[x][y][t][1][f2]--->f[nx][ny][t+1][0][f2]
,但是选了永久卷轴后我们要记录选的这个点的坐标(x,y),不妨这样考虑,假设最后我们我们在某个点使用了永久,所以一开始直接暴力枚举最后那个点被选为永久,这样的复杂度为:n*m*T*n*m*2*2
,所以会TLE; -
突破点1:
永久卷轴只有在我们使用后在回到永久卷轴的使用地方它才不一样,不然就跟临时卷轴一样,即A-B-C-D-A与A-A-A-A-A等效,所以考虑每个点被选为永久卷轴的时候,直接考虑他在原地呆了多久,最长时间为T,复杂度为T*N*M*T*2*2
,最坏1e8
,最后竟然过了,下面是记忆化搜索的写法
,注意可行性剪枝;
假设达到终点的时刻为t2
,当前的时刻为t1
,满足:
t 2 − t 1 + 1 ≥ △ x , △ x 为 曼 哈 顿 距 离 {\color{Red} t2-t1+1\ge \bigtriangleup x,\bigtriangleup x为曼哈顿距离 } t2−t1+1≥△x,△x为曼哈顿距离
t 2 ≥ m a x n , 不 合 法 的 情 况 发 现 为 m a x n − t 1 + 1 < △ x {\color{Red} t2\ge maxn,不合法的情况发现为maxn-t1+1<\bigtriangleup x} t2≥maxn,不合法的情况发现为maxn−t1+1<△x -
记忆化写法
class Solution {
public:
int dx[5]={0,1,0,-1,0};
int dy[5]={1,0,-1,0,0};
int n,m;
int maxn;
bool st[60][60][110][2][2]={false};
bool dfs(int x,int y,int t,int f1,int f2,const vector<vector<string>>& maze){
if(x==n-1&&y==m-1) return true;
//可行性剪枝
if(t>=maxn) return false;
if(maxn-t+1<n-1-x+m-1-y) return false;
if(st[x][y][t][f1][f2]==true) return false;
st[x][y][t][f1][f2]=true;
//考虑转移
for(int i=0;i<5;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||nx>=n||ny<0||ny>=m) continue;
if(maze[t+1][nx][ny]=='.'){
if(dfs(nx,ny,t+1,f1,f2,maze)) return true;
}
else{
//使用临时转移
if(f1==1){
if(dfs(nx,ny,t+1,0,f2,maze)) return true;
}
if(f2==1){
for(int j=t+1;j<=maxn;j++){
if(dfs(nx,ny,j,f1,0,maze)) return true;
}
}
}
}
return false;
}
bool escapeMaze(vector<vector<string>>& maze) {
n=maze[0].size(),m=maze[0][0].size();
maxn=maze.size()-1;
if(dfs(0,0,0,1,1,maze)) return true;
else return false;
}
};
- 递推写法(待补)