题目
假设存在一个m*n的栅格,编写函数计算从左下角(坐标:0, 0)走右上角(坐标:m, n)的路径有多少种。只能沿栅格线走,且不能反向走,既只能向上或向右走。
一、解法思路
题目的主要解题思路可以用递归来实现,比较方便快捷,下面讨论的方法是我降低了时间复杂度乱写的。
1.
-
求到某个点A(n,m)路径数,我们可以通过求到一个中间点的路径个数,在乘上中间的到A(n,m)的路径数,然后所有中间点在求和。当距离为1格时,那么中间点到A(n,m)只有一条路径了。
-
如图:A(1,0)到A(1,1)只有一条路,A(0,1)到A(1,1)也只有一条路,从A(0,0)到A(1,1)只有这两条路。
同理,那么从A(0,0)到A(2,1)的路径数=
从A(0,0)到A(1,1)的路径数
+从A(0,0)到A(2,0)的路径数 -
矩阵初始化:因为向右只有一条路径,A(n,0) = 0,向上直走也只有一条路径,A(0,m) = 0。
那么我们就可以求得到A(n,m)的公式:
截屏时图像偏移了
2.对称简化
- 在计算过程中仔细观察我们可以发现,关于角度为45 度的直线对称的值相等,因为当我们把行当成列时,计算方法完全一样。
- 也就是说我们只需要计算左下角的三角形,就可以的到整个矩阵的路径数值。
- 还有一点就是当要求的点是N*N时,我们只需要计算以A(0,n) 和A(n,0) 为对角线的下三角,然后A(n,m) 的值等于对角线上所有点值的平方的和。
3.分类
- 有两种出现的情况:A(n,m)中,长度length_n大于高度length_m, 或者高度length_m大于长度length_n的情况(我把等于归为其中的一种)。
- 那么计算的步骤为先将矩阵n*n 部分用对称简化计算,然后在计算额外的部分,这样可以将时间复杂度 O(n^2) 减到O(n^2 /2 ).
二、代码
代码如下:
#include <iostream>
#include <string.h>
#define SIZE 50
class distance
{
public:
int getDistan();
distance(int n, int m);
int calculation();
int distan;
int length_n;
int length_m;
int matrix[SIZE][SIZE];
};
int distance::getDistan()