问题

一个N×N的网格,你一开始在(1,1),即左上角。每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N,N),即右下角有多少种方法。

但是这个问题太简单了,所以现在有M个格子上有障碍,即不能走到这M个格子上。(数据保证起始点和终止点无障碍物,并且起点到终点至少存在一条通路)

输入描述

输入文件第1行包含两个非负整数N,M,表示了网格的边长与障碍数。

接下来M行,每行两个不大于N的正整数x,y。表示坐标(x,y)上有障碍不能通过,且有1≤x,y≤n,且起点到终点一定可以走通,并请注意障碍坐标有可能相同。

输出描述

一个非负整数,到达(N,N)的路径数。

样例输入 1

3 1
3 1
样例输出 1

5
提示

数据范围与提示
对于100%的数据,有N≤20。请给出c++代码

思考

理解问题情况

用户的问题是,给定一个N x N的网格,起点为(1,1),终点为(N,N),移动只能向右或向下。网格中有M个障碍,不能通过这些单元格。起点和终点都不受障碍影响。障碍可能有重复坐标,计算从起点到终点的不同路径数。

考虑障碍影响

在路径总数大时,障碍物会显著减少通路。使用动态规划计算每个点的通路数,忽略障碍物。

标记障碍物

最重要的是确保只访问一个前一个单元格,并且避免障碍物重复。使用集合或布尔网格标记障碍物。

提交C++代码

规划网格路径

初始化一个大小为N+1xN+1的网格,并标记障碍。通过动态规划,计算出从起点到目标点的路径数。

初始化动态规划表

正在整理测试代码,确保样本输入与输出相符。初始化DP表为0。继续推进。

更新动态规划表格

我正在通过逐格计算来更新DP表格。障碍物被设为0,其他格子通过前面格子的和来填充。最终,我找到了满足条件的路径数。

设计代码大纲

我正在设计代码大纲,处理障碍物和边界条件,确保有效的路径规划。

回答

To solve this problem, we will use dynamic programming. We'll create a 2D array dp where dp[i][j] represents the number of ways to reach cell (i, j) from (1, 1). Since we can only move right or down, we can calculate dp[i][j] based on the values of dp[i-1][j] and dp[i][j-1], unless the cell (i, j) is an obstacle.

Below is the C++ code that implements this logic:

#include <iostream> #include <vector> using namespace std; int main() { int N, M; cin >> N >> M; vector<vector<bool>> obstacle(N + 1, vector<bool>(N + 1, false)); for (int i = 0; i < M; ++i) { int x, y; cin >> x >> y; obstacle[x][y] = true; } vector<vector<long long>> dp(N + 1, vector<long long>(N + 1, 0)); dp[1][1] = 1; // Starting point for (int i = 1; i <= N; ++i) { for (int j = 1; j <= N; ++j) { if (obstacle[i][j]) { dp[i][j] = 0; } else if (!(i == 1 && j == 1)) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } } cout << dp[N][N] << endl; return 0; }

Explanation:

  • We read the grid size N and the number of obstacles M.
  • We create a 2D boolean array obstacle to mark the positions of the obstacles.
  • We initialize the dp array with zeros and set dp[1][1] to 1 since there's only one way to be at the starting position.
  • We iterate through each cell in the grid:
    • If the current cell is an obstacle, we set dp[i][j] to 0.
    • If it's not the starting cell, we calculate the number of ways to reach it by summing the ways to reach the cell above it and the cell to the left of it.
  • Finally, we output the value of dp[N][N], which is the number of ways to reach the bottom-right corner.

Sample Input:

3 1
3 1

Sample Output:

5

This output matches the expected result as per the problem description.

分享这个问答