【问题描述】在平面上有一些二维点阵。这些点的编号就像二维数组的编号一样,从上到下依次为第1~n行,从左到右依次为第1~m列,每个点可以用行号和列号表示。
现在有个人站在第1行第1列,他要走到第n行第m列,只能向右或者向下走。
【注意】如果行号和列数都是偶数,则不能走入这一格。
问有多少种方案。
【输入格式】
一行,包含两个整数n和m。
【输出格式】
一个整数,表示答案。
【样例输入】
20 21
【样例输出】
92378
【数据规模】
数据范围为 n >= 1, m <= 30。
【解析】
设n=5,m=5,则本题的示意图如下图所示,方格中共有4个方格不能走入,其他方格可以通过向下和向右走入。
本题可以采用动态规划的方法解决。
设f[i][j]表示走到第i行,第j列时的走法数量,那么走到f[i][j]的方法只有两种,即从上面走过来的或者从左边走过来,故[i][j]的做法是这两种走法之和,即,
f[i][j] = f[i-1][j] + f[i][j-1]
这也是状态转移方程,需要注意以下两点。
(1)该状态转移方程必须满足i和j不同时为偶数,同,如果i和j同时为偶数,则该方格的走法为0。
(2)初始状态为f[1][1]=1,即到达f[1][1]一共有1种方法。
【参考程序如下】
cpp
#include <iostream>
using namespace std;
int n,m,ans;
int i,j;
int f[35][35];
int main(int argc, char** argv) {
cin >> n >> m;
if(n % 2 == 0 && m % 2 == 0)
{
cout << 0;
return 0;
}
for(i = 1; i <= n; i++)
for(j = 1; j <= m;j++)
{
if(i == 1 && j == 1)
f[i][j] = 1;
//初始化
else if(i % 2 == 1 || j % 2 == 1) //方格不全为偶数
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
cout << f[n][m] << endl;
return 0;
}
【程序运行结果如下】