你所在城市的街道好像一个棋盘,有 a 条南北方向的街道和 b条东西方向的街道。南北方向的 a 条街道从西到东依次编号为 l 到 a,而东西方向的 b 条街道从南到北依次编号为 l 到 b,南北方向的街道 i 和东西方向的街道 j 的交点记为 (i,j)。
你住在 (1,1) 处,而学校在 (a,b) 处,你骑自行车去上学,自行车只能沿着街道走,而且为了缩短时间只允许沿着向东和北的方向行驶。
现在有 n 个交叉路口在施工 (X1,Y1)、(X2,Y2)、………、(Xn,Yn),这些路口是不能通车的。
问你上学一共有多少走法?
输入格式
第一行包含三个整数 a,b,n,分别表示街道的范围,有 n 个路口在维修。
接下来 n 行,每行两个整数 Xi,Yi,描述路口的位置。
数据范围:1≤a,b≤16,1≤n≤10,1≤Xi≤a,1≤yi≤b。
输出格式
输出一个整数表示从 (1,1) 到 (a,b)的行车路线总数。
样例解释
输出时每行末尾的多余空格,不影响答案正确性
样例输入
5 4 3
2 2
2 3
4 2
样例输出
5
思路: 动态规划找出地推关系式
#include <iostream>
//#include <algorithm>
using namespace std;
//pair<int, int> block[15];
bool vis[20][20]; //记录可以走的点
int dp[20][20];
int main() {
int a, b, n;
cin >> a >> b >> n;
for (int i = 0; i < n; i++) { //记录障碍
int temp1, temp2;
cin>>temp1>>temp2;
vis[temp1][temp2] = true;
}
vis[1][1] = true;
// cout<<"vis\n";
// for (int i = 1; i <= b; i++) {
// for (int j = 1; j <= a; j++) {
// cout<<vis[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<endl<<endl;
dp[1][1] = 1;
for (int i = 1; i <= a; i++) {
for (int j = 1; j <= b; j++) {
if (vis[i][j] == false) {
if (i) { //考虑到达最后一个点的情况, 只有往上和往右两种情况,写出递推关系式 dp[i][j] = dp[i-1][j] + dp[i][j+1]
dp[i][j] += dp[i-1][j];
}
if (j) {
dp[i][j] += dp[i][j-1];
}
}
}
}
// cout<<"dp\n";
// for (int i = 1; i <= a; i++) {
// for (int j = 1; j <= b; j++) {
// cout<<dp[a][b]<<" ";
// }
// cout<<endl;
// }
// cout<<endl<<endl;
cout<<dp[a][b];
return 0;
}