题目:https://leetcode-cn.com/problems/Db3wC1/
class Solution {
private:
vector<vector<int>>udlr = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}, {0, 0}}; // 往上下左右走
int limittime;
vector<int>rightPos;
int dp[51][51][101][2][2] = {0}; // dp数组 1代表失败,0代表未记录
public:
bool goMaze(vector<vector<string>>& maze, vector<int>pos, int time, bool used1, bool used2){ // pos代表位置,time代表时间,used1表示临时小时术,used2表示永久消失术
int cury = pos[0], curx = pos[1]; // 当前位置
if(dp[cury][curx][time][used1][used2]) return false; // 动态规划
//失败条件:当前时间耗尽且位置不在终点
if(time == limittime && (cury != this->rightPos[0] || curx != this->rightPos[1])) return false;
//成功条件:位置在终点
if(cury == this->rightPos[0] && curx == this->rightPos[1]) return true;
int nexttime = time+1; // 当时间为limittime 且 未到达终点则失败
// 1.走的情况:枚举上下左右走
for(vector<int> &vec : udlr){
int nexty = cury + vec[0]; // 下一个位置的y坐标
int nextx = curx + vec[1]; // 下一个位置的x坐标
// 看下一个位置是否在地图里,如果不是则continue循环
if(nextx < 0 || nextx > rightPos[1] || nexty < 0 || nexty > rightPos[0]) continue;
//判断下一个位置的合法性,并选择是否使用卷轴
// 可能性1:下一个位置不是陷阱 情况:1)走
if(maze[nexttime][nexty][nextx] == '.'){
if(goMaze(maze, {nexty, nextx}, nexttime, used1, used2)) return true; // 走
}
// 可能性2:下一个位置是陷阱 情况:1)使用道具
else{
if(used1){ // 使用道具1
if(goMaze(maze, {nexty, nextx}, nexttime, !used1, used2)) return true;
}
if(used2){ // 使用道具2
vector<int>vec1 = changeMap(maze, nexty, nextx);
if(goMaze(maze, {nexty, nextx}, nexttime, used1, !used2)) return true;
recoverMap(maze, nexty, nextx, vec1); // !
}
}
}
// 四个方向 或者不走 都走不了,返回走不了
dp[cury][curx][time][used1][used2] = 1;
return false;
}
vector<int> changeMap(vector<vector<string>>& maze, int y, int x){
vector<int>vec1; int count = 0;
for(vector<string> &vec : maze){
if(vec[y][x] == '#') vec1.push_back(count);
count++; vec[y][x] = '.';
}
return vec1;
}
void recoverMap(vector<vector<string>>& maze, int y, int x, vector<int>vec){
for(int i : vec) maze[i][y][x] = '#';
}
bool escapeMaze(vector<vector<string>>& maze) {
this->limittime = maze.size()-1;
int yLength = maze[0].size(), xLength = maze[0][0].size();
this->rightPos = {yLength-1, xLength-1};
if(goMaze(maze, {0, 0}, 0, true, true)) return true;
else return false;
}
};