一、问题描述
在平面上有一些二维的点阵。
这些点的编号就像二维数组的编号一样,从上到下依次为第1
至第n
行,从左到右依次为第1
至第m
列,每一个点可以用行号和列号来表示。
现在有个人站在第1
行第1
列,要走到第n
行第m
列。只能向右或者向下走。
注意,如果行号和列数都是偶数,不能走入这一格中。
问有多少种方案。
输入格式: 输入一行包含两个整数n
,m
。
输出格式: 输出一个整数,表示答案。
样例1输入:3 4
样例1输出:2
样例2输入:6 6
样例2输出:0
评测用例规模与约定:
对于所有评测用例,1 ≤ n ≤ 30
,1 ≤ m ≤ 30
。
二、问题分析
看到题目应该能想到用动态规划,每一次的状态跟前面的状态都有关系。
- 确定dp数组以及下标的含义: d p [ i ] [ j ] dp[i][j] dp[i][j]:表示从 ( 1 , 1 ) (1,1) (1,1)出发,到达 ( i , j ) (i,j) (i,j)有 d p [ i ] [ j ] dp[i][j] dp[i][j]不同方案。
- 确定递推公式:格子
(
i
,
j
)
(i,j)
(i,j)可以
(
i
−
1
,
j
)
(i-1,j)
(i−1,j)向下到达,也可以从
(
i
,
j
−
1
)
(i,j-1)
(i,j−1)向右到达,所以递推公式:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][j]=dp[i-1][j]+dp[i][j-1] dp[i][j]=dp[i−1][j]+dp[i][j−1]
。不过要注意,当 i i i 和 j j j 为偶数时, d p [ i ] [ j ] dp[i][j] dp[i][j]则应该保持初始状态(初始状态为0)。 - 初始化dp数组:从 ( 1 , 1 ) (1,1) (1,1)到 ( i , 1 ) (i,1) (i,1)的方案只有一种,所以 d p [ i ] [ 1 ] dp[i][1] dp[i][1]一定都是1, d p [ 1 ] [ j ] dp[1][j] dp[1][j]同理。
三、代码实现
// 编程软件:Dev-C++ 5.4.0
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; i++) dp[i][1] = 1; // 初始化
for (int j = 1; j <= m; j++) dp[1][j] = 1; // 初始化
for (int i = 2; i <= n; i++) {
for (int j = 2; j <= m; j++) {
if ((i % 2 == 0) && (j % 2 == 0)) continue; // 行号和列数都是偶数,直接返回循环
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; // 递推公式
}
}
cout << dp[n][m];
return 0;
}
四、小结
与本题类似的题目:力扣:63. 不同路径 II