[CareerCup 8.2] 机器人的路径
Imagine a robot sitting on the upper left hand corner of an NxN grid The robot can only move in two directions: right and down How many possible paths are there for the robot?
翻译:一个机器人在一个NxN的方格上的左上角,只能向下或向右走,请问到达右下角的路径有多少条?
分析:机器人在一个方格中,只有两种选择,要么是向下走,要么是向右走。我们用f(m, n)表示机器人在一个mxn的矩形的左上角上向下或向左走到右下角的路径的条数,我们很容易得出递归式子:f(m, n) = f(m-1, n) + f(m, n-1)。其中f(m-1, n)表示机器人向下走时的情况,f(m, n-1)表示机器人向右走的情况。注意f(1, n) = f(m, 1) = 1。
基于这点,我们很容易写出递归的代码:
// 机器人在一个m*n的矩形上只向右或向下走的路径数
int get_paths(int m, int n)
{
// 对于1*或*1的矩形,只有一条路径
if (m == 1 || n == 1)
return 1;
// 向下走 + 像右走
return get_paths(m - 1, n) + get_paths(m, n - 1);
}
// 机器人在一个n*n的正方形上只向右或向下走的路径数
int get_paths(int n)
{
return get_paths(n, n);
}
但是,我们发现这样的代码中,会有很多重复计算。我们可以将递归的结果用一个数组存起来,如果发现不存在,我们就递归计算下去,如果存在的话,就直接取出使用。
另外,我们可以采用DP(动态规划的思想)来解决这题。怎么说呢,因为我们从递归的写法看到,问题的结果往往依赖于子问题的结果。DP的思想就是,不管有用没用,我们将所有的子问题的值都算出来,然后由子问题组成最终我们要求的问题。代码如下:
// 机器人在一个n*n的正方形上只向右或向下走的路径数,DP求解
int get_paths_dp(int n)
{
int **a = new int*[n];
int i, j;
for (i = 0; i < n; i++)
a[i] = new int[n];
// 初始化,对于1*或*1的矩形,只有一条路径
for (i = 0; i < n; i++)
{
a[0][i] = 1;
a[i][0] = 1;
}
for (i = 1; i < n; i++)
for (j = 1; j < n; j++)
a[i][j] = a[i - 1][j] + a[i][j - 1];
j = a[n - 1][n - 1];
for (i = 0; i < n; i++)
delete[] a[i];
delete[] a;
return j;
}
本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。