Leetcode 多维度dp+优先队列+bfs
2022/1/13 6:07:24
本文主要是介绍Leetcode 多维度dp+优先队列+bfs,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
LC 1263. 推箱子
题目:推箱子中箱子的最少移动步数,人的次数不算
方法一:优先队列+BFS
Node{步数,人x,人y,箱子x,箱子y},优先队列按步数从小到大排序,每次取最小的出来更新(相当于Dijkstra变形),vis记录节点是否访问。
也可以完全用dis数据,记录达到某状态的最小距离,按dis更新,那就是完全Dijkstra了
人移动可以推箱子,也可能不推,判断一下,没有推箱子的话步数不变。
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
由于步数要么加1,要么不变,即只用01两种。可以用01队列代替优先队列,也就是01BFS。
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; } };
这篇关于Leetcode 多维度dp+优先队列+bfs的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-10Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势
- 2025-01-03用LangChain构建会检索和搜索的智能聊天机器人指南
- 2025-01-03图像文字理解,OCR、大模型还是多模态模型?PalliGema2在QLoRA技术上的微调与应用