携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
路径计数2
题目描述
一个的网格,你一开始在,即左上角。每次只能移动到下方相邻的格子或者右方相邻的格子,问到达,即右下角有多少种方法。
但是这个问题太简单了,所以现在有个格子上有障碍,即不能走到这个格子上。
输入格式
输入文件第行包含两个非负整数,表示了网格的边长与障碍数。
接下来行,每行两个不大于的正整数。表示坐标上有障碍不能通过,且有,且至少有一个大于,并请注意障碍坐标有可能相同。
输出格式
一个非负整数,为答案后的结果。
样例 #1
样例输入 #1
3 1
3 1
样例输出 #1
5
提示
对于的数据,有;
对于的数据,有;
对于的数据,有;
对于的数据,有。
首先,题目描述的重点在于每次只能移动到下方相邻的格子或者右方相邻的格子,所以,我们就可以得出结论:到达第n个格子的路径数量是这个格子左边的格子的路径数量+上边格子的路径数量。我们定义一个DP数组,DP[i][j](也就是状态)代表第M[i][j]个格子的路径数量,根据上面的推论,我们可以得出状态转移方程:DP[i][j] = DP[i-1][j]+DP[i][j-1];
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,m,g[1001][1001];
bool v[1001][1001]; //判断是否有障碍
int main()
{
int x,y;
memset(g,0,sizeof g); //初始化步数都为0
memset(v,0,sizeof v); //路障都为0
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
scanf("%d%d",&x,&y);
v[x][y]=1;
}
g[0][1]=1; //初始化第一步棋子
for(int i=1;i<=n;i++)//逐步开始递推
for(int j=1;j<=n;j++) {
g[i][j]=(g[i-1][j]+g[i][j-1])%100003; //一定要取模
if(v[i][j]==1)//这个地方是障碍,那么到这里的步数都为0
g[i][j]=0;
}
printf("%d",g[n][n]);//最后终点的部署及为答案。
return 0;//结束
}