您好,登录后才能下订单哦!
在计算机科学中,路径问题是一个经典的问题,尤其是在图论和动态规划中。路径问题通常涉及在一个网格或图中找到从起点到终点的所有可能路径。本文将探讨如何使用C++实现不同的路径问题,包括简单的网格路径问题和带有障碍物的路径问题。
假设有一个 m x n
的网格,机器人位于左上角(起点),每次只能向下或向右移动一步。问:机器人从起点到右下角(终点)有多少种不同的路径?
我们可以使用动态规划来解决这个问题。定义一个二维数组 dp
,其中 dp[i][j]
表示从起点 (0, 0)
到 (i, j)
的不同路径数。
dp[0][0] = 1
,因为起点到起点只有一种路径。dp[i][j] = dp[i-1][j] + dp[i][j-1]
,因为机器人只能从上方或左方移动到当前位置。#include <iostream>
#include <vector>
using namespace std;
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n, 1));
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
int main() {
int m = 3, n = 7;
cout << "Number of unique paths: " << uniquePaths(m, n) << endl;
return 0;
}
O(m * n)
,因为我们需要填充整个 dp
数组。O(m * n)
,用于存储 dp
数组。现在假设网格中有一些障碍物,机器人不能通过障碍物。问:机器人从起点到终点的不同路径数是多少?
我们可以继续使用动态规划来解决这个问题。定义一个二维数组 dp
,其中 dp[i][j]
表示从起点 (0, 0)
到 (i, j)
的不同路径数。
(0, 0)
是障碍物,则 dp[0][0] = 0
,否则 dp[0][0] = 1
。(i, j)
是障碍物,则 dp[i][j] = 0
,否则 dp[i][j] = dp[i-1][j] + dp[i][j-1]
。#include <iostream>
#include <vector>
using namespace std;
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
if (m == 0) return 0;
int n = obstacleGrid[0].size();
vector<vector<int>> dp(m, vector<int>(n, 0));
dp[0][0] = (obstacleGrid[0][0] == 0) ? 1 : 0;
for (int i = 1; i < m; ++i) {
if (obstacleGrid[i][0] == 0 && dp[i-1][0] == 1) {
dp[i][0] = 1;
}
}
for (int j = 1; j < n; ++j) {
if (obstacleGrid[0][j] == 0 && dp[0][j-1] == 1) {
dp[0][j] = 1;
}
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (obstacleGrid[i][j] == 0) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
int main() {
vector<vector<int>> obstacleGrid = {
{0, 0, 0},
{0, 1, 0},
{0, 0, 0}
};
cout << "Number of unique paths with obstacles: " << uniquePathsWithObstacles(obstacleGrid) << endl;
return 0;
}
O(m * n)
,因为我们需要填充整个 dp
数组。O(m * n)
,用于存储 dp
数组。在上述解法中,我们使用了一个二维数组 dp
来存储中间结果。然而,我们可以通过观察发现,dp[i][j]
只依赖于 dp[i-1][j]
和 dp[i][j-1]
,因此我们可以使用一维数组来优化空间复杂度。
#include <iostream>
#include <vector>
using namespace std;
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
if (m == 0) return 0;
int n = obstacleGrid[0].size();
vector<int> dp(n, 0);
dp[0] = (obstacleGrid[0][0] == 0) ? 1 : 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (obstacleGrid[i][j] == 1) {
dp[j] = 0;
} else if (j > 0) {
dp[j] += dp[j-1];
}
}
}
return dp[n-1];
}
int main() {
vector<vector<int>> obstacleGrid = {
{0, 0, 0},
{0, 1, 0},
{0, 0, 0}
};
cout << "Number of unique paths with obstacles: " << uniquePathsWithObstacles(obstacleGrid) << endl;
return 0;
}
O(m * n)
,因为我们需要遍历整个网格。O(n)
,因为我们只使用了一维数组 dp
。本文介绍了如何使用C++实现不同的路径问题,包括简单的网格路径问题和带有障碍物的路径问题。我们通过动态规划的方法解决了这些问题,并进一步优化了空间复杂度。路径问题是动态规划中的经典问题,掌握这些方法对于解决类似的图论问题非常有帮助。
在实际应用中,路径问题可以扩展到更复杂的情况,例如允许斜向移动、路径权重不同等。通过灵活运用动态规划和其他算法,我们可以解决更多复杂的路径问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。