最小路径总和

时间:2017-09-10 19:04:18

标签: c++ algorithm dynamic-programming depth-first-search

我正在研究一个算法问题,你必须找到一个网格的最小路径总和,你可以向上,向下,向左或向右移动,你不能重复一个正方形。我写了一个递归解决方案来解决它(我知道DP会更好),但它每次输出0作为答案,但发现最小总和为215(应该是87)。我如何修复代码来解决它?

另外,我怎么能用DP来实现呢?

这是我的代码:

#include<fstream>
#include<iostream>
#include<algorithm>

int rows;
int cols;
/*
 * assumes max grid size is 1000x1000
 * could go larger if necessary, but memory use will increase
 */
int grid[1000][1000]; 
bool isMarked[1000][1000];

int calc(int row, int col, int sum) {
    if (isMarked[row][col])
        return INT_MAX - sum;
    isMarked[row][col] = true;
    sum += grid[row][col];
    if (row == rows-1 && col == cols-1)
        return sum;

    int ans[4];
    if (row-1 >= 0) 
        ans[0] = calc(row-1, col, sum);
    if (row+1 < rows) 
        ans[1] = calc(row+1, col, sum);
    if (col+1 < cols)
        ans[2] = calc(row, col+1, sum);
    if (col-1 >= 0)
        ans[3] = calc(row, col-1, sum);
    isMarked[row][col] = false;
    return std::min(std::min(ans[0], ans[1]), std::min(ans[2], ans[3]));
}

int main() {
    std::ifstream fin("sum.in");
    fin >> rows >> cols;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            fin >> grid[i][j];

    int ans = calc(0, 0, 0);

    std::ofstream fout("sum.out");
    fout << ans << std::endl;
}

1 个答案:

答案 0 :(得分:0)

可能是这样的:

int calc(int row, int col, int sum) {
    if (isMarked[row][col])
        return INT32_MAX;
    if (row == rows-1 && col == cols-1)
        return sum+grid[row][col];

    isMarked[row][col] = true;
    int ans[4] = {INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX};
    if (row-1 >= 0)
        ans[0] = calc(row-1, col, sum+grid[row][col]);
    if (row+1 < rows)
        ans[1] = calc(row+1, col, sum+grid[row][col]);
    if (col+1 < cols)
        ans[2] = calc(row, col+1, sum+grid[row][col]);
    if (col-1 >= 0)
        ans[3] = calc(row, col-1, sum+grid[row][col]);
    isMarked[row][col] = false;

    return std::min(std::min(ans[0], ans[1]), std::min(ans[2], ans[3]));
}