文章目录
方格路径
内存限制: 256 Mb
时间限制: 1000 ms
题目描述
在一个由 n×m个方格构成的图中,有 k 个方格是禁止进入的。请计算从左上角 (1,1)(1,1) 出发,每步朝右方或下方移动,不经过禁入的方格,最后到达右下角 (n,m) 的路径条数。由于答案很大,输出模 1,000,000,007 的余数。
输入格式
第一行:三个正整数表示n,m与 k。
第二行到第 n+1行:第 i+1行表示一个禁入方格的坐标 ( x i , y i ) (x_i,y_i) (xi,yi)。保证 ( x i , y i ) (x_i,y_i) (xi,yi) 不会等于 (1,1) 或 (n,m),也不会有一个坐标重复出现两次。
输出格式
单个自然数:表示路径数模 1,000,000,007 的余数。
数据范围
- 对于 30% 的数据, 0 ≤ k ≤ 200 0\leq k\leq 200 0≤k≤200
- 对于60% 的数据, 0 ≤ k ≤ 1500 0\leq k\leq 1500 0≤k≤1500
- 对于 100% 的数据, 0 ≤ k ≤ 3000 0\leq k\leq 3000 0≤k≤3000
- 1 ≤ n , m ≤ 1 0 5 1\leq n,m\leq 10^5 1≤n,m≤105。
样例数据
输入:
100000 100000 4
50001 50001
50000 50000
50000 50001
50001 50000
输出:
999612315
输入:
2 2 2
2 1
1 2
输出:
0
递推解法一:递推
初看本题很像leecode 中63题。 不同路径 ,我们也可以使用Leecode中递推解法。 可以得到30分。 主要是本题得N和M的取值范围是100000.
算法的时间复杂度
O ( N × M ) O(N\times M) O(N×M) .
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;
inline int read()
{
int x = 0, f = 1;
char s = getchar();
while (s < '0' || s > '9')
{
if (s == '-')
f = -f;
s = getchar();
}
while (s >= '0' && s <= '9')
{
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
return x * f;
}
class Solution
{
public:
int uniquePathsWithObstacles(vector<vector<int>> &o)
{
int n = o.size();
if (n == 0)
return 0;
int m = o[0].size();
vector<vector<int>> f(n, vector<int>(m));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
//当o[i][j]==1 时候, 有石头挡住了。这点需要维持0.
//我们要没有石头的地方开始转移。
if (!o[i][j])
{
if (!i && !j)
f[i][j] = 1;
else
{
if (i)
f[i][j] += f[i - 1][j];
if (j)
f[i][j] += f[i][j - 1];
}
}
}
return f[n - 1][m - 1