[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;
}

posted on 2011-12-22 22:41  小橋流水  阅读(235)  评论(0编辑  收藏  举报

导航