题目描述
一个 N×N 的网格,你一开始在 (1,1),即左上角。每次只能移动到下方相邻的格子或者右方相邻的格子,问到达 (N,N),即右下角有多少种方法。
但是这个问题太简单了,所以现在有M个格子上有障碍,即不能走到这M个格子上。(依然简单)
输入格式
- 输入文件第1行包含两个非负整数N,M,表示了网格的边长与障碍数。
- 接下来 M 行,每行两个不大于 N 的正整数 x,y 。表示坐标 (x,y) 上有障碍不能通过,且有 1 ≤ x,y ≤ n,且 x,y 至少有一个大于1,并请注意障碍坐标有可能相同。
输出格式
- 一个非负整数,为答案 mod100003 后的结果。
样例
输入#1:
3 1
3 1
输出#1:
5
说明
对于 20% 的数据,有 N≤3 ;
对于 40% 的数据,有 N≤100 ;
对于 40% 的数据,有 M=0 ;
对于 100% 的数据,有 N ≤ 1000, M ≤ 100000 ;
思路
这是一道入门动态规划的题,建立状态转移方程为:dp[i][j] = dp[i-1][j] + dp[i][j-1];当然还得判断一下 i, j 有没有越界。
代码如下,详见注释:
#include <iostream>
#define max 1001
#define mod 100003 //数据范围!
using namespace std;
int n, m, sum=0;
int map[max][max];
int dp[max][max];
int main()
{
int x, y;
cin >> n >> m;
for(int i=1; i<=m; i++)
{
cin >> x >> y;
map[x][y] = 1; //标记不能走的地方;
}
dp[1][1] = 1; //初始化起点的路径值为1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++) //遍历图更新路径次数
{
if (map[i][j]) dp[i][j] = 0;
else {
if (i != 1) dp[i][j] = (dp[i][j]+dp[i-1][j])%mod;
if (j != 1) dp[i][j] = (dp[i][j]+dp[i][j-1])%mod;
}
}
}
cout << dp[n][n] << endl;
return 0;
}
蒟蒻一只,欢迎指正