题目描述
有一个n*m的格子,从(0,0)走到(n-1, m-1)有多少种走法?
如果在格子中有q个障碍物,有多少种走法?
解题思路
- dp[n][m];
- dp[i][j]表示从(0,0)第i行第j个格子有多少种走法。障碍物的点置“-1”;
- 初始化dp[0][i]为1,障碍物后面均为-1,dp[i][0]同理。
- return dp[n-1][m-1]。
代码
#include <iostream>
#include <vector>
using namespace std;
int paceNum(int m, int n, vector<vector<int>>& blocks)
{
vector<vector<int>> dp(m, vector<int>(n, 0));
for (int i = 0; i < blocks.size(); ++i)
dp[blocks[i][0]][blocks[i][1]] = -1;
dp[0][0] = 1;
int i = 0;
for (i = 1; i < n; ++i)
{
if (dp[0][i] == -1)
break;
dp[0][i] = dp[0][i - 1];
}
if (i != n)
{
for (int j = i; j < n; j++)
dp[0][j] = -1;
}
i = 0;
for (i = 1; i < m; ++i)
{
if (dp[i][0] == -1)
break;
dp[i][0] = dp[i-1][0];
}
if (i != m)
{
for (int j = i; j < n; j++)
dp[j][0] = -1;
}
for (i = 1; i < n; ++i)
{
for (int j = 1; j < m; ++j)
{
if (dp[i][j] != -1)
{
if (dp[i - 1][j] == -1 && dp[i][j - 1] != -1)
dp[i][j] = dp[i][j - 1];
else if (dp[i - 1][j] != -1 && dp[i][j - 1] == -1)
dp[i][j] = dp[i - 1][j];
else if (dp[i - 1][j] != -1 && dp[i][j - 1] != -1)
dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % 1000000007;
else
dp[i][j] = -1;
}
}
}
return dp[m - 1][n - 1];
}
int main()
{
int m, n, q;
cin >> m >> n >> q;
vector<vector<int>> blocks;
while (q--)
{
int x, y;
cin >> x >> y;
vector<int> temp{ x-1, y-1 };
blocks.push_back(temp);
}
int ans = paceNum(m, n, blocks);
cout << ans << endl;
return ans;
}