有些障碍的 unique path

我第一时间想到的方案是化归而不是规划,毕竟之前的问题类似,所以就有了这个版本:

int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
    if (obstacleGrid.empty()){
        return 0;
    }
    const int begin = obstacleGrid.front().front();
    if (begin == 1){
        return 0;
    }
    const size_t m = obstacleGrid.size();
    const size_t n = obstacleGrid.front().size();
    
    vector<vector<int>> record((m), vector<int>(n));
    function<int(size_t, size_t)> getPathsNum;
    getPathsNum = [&](int a, int b)
    {
        if (obstacleGrid[a][b] == 1){
            return 0;
        }
        
        if (a == 0 && b == 0){
            return 1;
        }
        int&& result = 0;
        if (a == 0){
            result = getPathsNum(0, b - 1);
            record[a][b] = result;
            return result;
        }
        if (b == 0){
            result = getPathsNum(a - 1, 0);
            record[a][b] = result;
            return result;
        }
        const int paths_num = record[a][b];
        if (paths_num != 0){
            return paths_num;
        }
        result = getPathsNum(a - 1, b) + getPathsNum(a, b - 1);
        record[a][b] = result;
        return result;
    };
    return getPathsNum(m - 1, n - 1);
}

感觉:嗯嗯,可以可以。一测时间, 92 ms。尼玛用 ruby 的都比我速度快,这玩毛。

后来发现我又陷入 DP 就是递归的思维定势里了,f(m, n) = f(m - 1, n) + f(m, n -1) 这个式子固然可以反着推,但正着填充不是更好?这才发现上面的版本根本不是用的动态规划的思想。

真正 DP 的思想是填充。当然填充也很简单大概意思就是 result[m, n] = result[m - 1, n] + result[m, n - 1]。这才是动规的思想好不拉!

能更省空间吗?我发现其实每一行的结果只依赖上一行,再往上的对它并没有直接影响。那还存储它们作甚?所以只需要一行数据的空间,然后逐行扫描。

int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
    if (obstacleGrid.empty() || obstacleGrid[0][0] == 1 ||
        obstacleGrid.back().back() == 1){
        return 0;
    }
    const size_t row_length = obstacleGrid[0].size();
    vector<int> row(row_length);
    auto const& first_row = obstacleGrid[0];
    bool is_blocked = false;
    for (size_t i = 0; i != row_length; ++i){
        if (is_blocked || first_row[i] == 1){
            row[i] = 0;
            is_blocked = true;
        }else{
            row[i] = 1;
        }
    }
    for (size_t i = 1; i != obstacleGrid.size(); ++i){
        for (size_t j = 0; j != row_length; ++j){
            if (obstacleGrid[i][j] == 1){
                row[j] = 0;
            }
            else if (j > 0){
                row[j] = row[j] + row[j - 1];
            }
        }
    }
    return row.back();
}
原文地址:https://www.cnblogs.com/wuOverflow/p/5045756.html