Leetcode 多维度dp+优先队列+bfs

LC 1263. 推箱子

方法一：优先队列+BFS

Node{步数，人x，人y，箱子x，箱子y}，优先队列按步数从小到大排序，每次取最小的出来更新（相当于Dijkstra变形），vis记录节点是否访问。

class Solution {
public:
bool vis[25][25][25][25];
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
int minPushBox(vector<vector<char>>& grid) {
memset(vis, 0, sizeof(vis));
priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq; // 取步数最小的
int row = grid.size(), col = grid[0].size();
int ax, ay, bx, by, ex, ey;
for(int i = 0;i < row;i++) {
for(int j = 0;j < col;j++) {
if(grid[i][j] == 'S') {
ax = i, ay = j;
grid[i][j] = '.';
}
if(grid[i][j] == 'B') {
bx = i, by = j;
grid[i][j] = '.';
}
if(grid[i][j] == 'T') {
ex = i, ey = j;
}
}
}
pq.push({0, ax, ay, bx, by}); // 步数，人，箱子
vis[ax][ay][bx][by] = true;
while(!pq.empty()) {
auto p = pq.top();pq.pop();
// cout << p[0] << " " << p[1] << " " << p[2] << " " << p[3] << " " << p[4] << endl;
if(p[3] == ex && p[4] == ey)  return p[0];
for(int i = 0;i < 4;i++) {
int nax = p[1]+dx[i], nay = p[2]+dy[i];  // 人
if(nax < 0 || nax >= row || nay < 0 || nay >= col || grid[nax][nay] == '#')  continue;
int nbx = (nax == p[3] && nay == p[4] ? p[3]+dx[i] : p[3]); // 箱子要么随人走，要么不动
int nby = (nax == p[3] && nay == p[4] ? p[4]+dy[i] : p[4]);
if(nbx < 0 || nbx >= row || nby < 0 || nby >= col || grid[nbx][nby] == '#')  continue;
int w = (nax == p[3] && nay == p[4]);  // 箱子移动了记1
if(!vis[nax][nay][nbx][nby]) {
vis[nax][nay][nbx][nby] = true;
pq.push({p[0]+w, nax, nay, nbx, nby});
}
}
}
return -1;
}
};


方法二：01队列+BFS

class Solution {
public:
bool vis[25][25][25][25];
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
int minPushBox(vector<vector<char>>& grid) {
memset(vis, 0, sizeof(vis));
deque<vector<int>> pq; // 01队列
int row = grid.size(), col = grid[0].size();
int ax, ay, bx, by, ex, ey;
for(int i = 0;i < row;i++) {
for(int j = 0;j < col;j++) {
if(grid[i][j] == 'S') {
ax = i, ay = j;
grid[i][j] = '.';
}
if(grid[i][j] == 'B') {
bx = i, by = j;
grid[i][j] = '.';
}
if(grid[i][j] == 'T') {
ex = i, ey = j;
}
}
}
pq.push_front({0, ax, ay, bx, by}); // 步数，人，箱子
vis[ax][ay][bx][by] = true;
while(!pq.empty()) {
auto p = pq.front();pq.pop_front();
// cout << p[0] << " " << p[1] << " " << p[2] << " " << p[3] << " " << p[4] << endl;
if(p[3] == ex && p[4] == ey)  return p[0];
for(int i = 0;i < 4;i++) {
int nax = p[1]+dx[i], nay = p[2]+dy[i];  // 人
if(nax < 0 || nax >= row || nay < 0 || nay >= col || grid[nax][nay] == '#')  continue;
int nbx = (nax == p[3] && nay == p[4] ? p[3]+dx[i] : p[3]); // 箱子要么随人走，要么不动
int nby = (nax == p[3] && nay == p[4] ? p[4]+dy[i] : p[4]);
if(nbx < 0 || nbx >= row || nby < 0 || nby >= col || grid[nbx][nby] == '#')  continue;
int w = (nax == p[3] && nay == p[4]);  // 箱子移动了记1
if(!vis[nax][nay][nbx][nby]) {
vis[nax][nay][nbx][nby] = true;
if(w == 0)  pq.push_front({p[0], nax, nay, nbx, nby});
else  pq.push_back({p[0]+w, nax, nay, nbx, nby});
}
}
}
return -1;
}
};

posted @ 2022-01-12 23:12  Rogn  阅读(15)  评论(0编辑  收藏  举报