C++ 最小路径和
我正在研究一个算法问题,你必须找到一个网格的最小路径和,你可以上下左右移动,你不能重复一个正方形。我编写了一个递归解决方案来解决它(我知道DP会更好),但它每次都输出0作为答案,但发现最小和是215(应该是87)。我如何修复代码来解决它 另外,我如何使用DP来实现这一点 这是我的密码:C++ 最小路径和,c++,algorithm,dynamic-programming,depth-first-search,C++,Algorithm,Dynamic Programming,Depth First Search,我正在研究一个算法问题,你必须找到一个网格的最小路径和,你可以上下左右移动,你不能重复一个正方形。我编写了一个递归解决方案来解决它(我知道DP会更好),但它每次都输出0作为答案,但发现最小和是215(应该是87)。我如何修复代码来解决它 另外,我如何使用DP来实现这一点 这是我的密码: #include<fstream> #include<iostream> #include<algorithm> int rows; int cols; /* * assu
#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;
}
#包括
#包括
#包括
int行;
int cols;
/*
*假设最大网格大小为1000x1000
*如有必要,可能会变大,但内存使用会增加
*/
整数网格[1000][1000];
布尔标记为[1000][1000];
整数计算(整数行、整数列、整数和){
如果(标记为[行][列])
返回INT_MAX-sum;
isMarked[row][col]=真;
总和+=网格[行][列];
if(行==行-1&&col==列-1)
回报金额;
int ans[4];
如果(第1行>=0)
ans[0]=计算值(第1行,列,和);
如果(行+1<行)
ans[1]=计算(行+1,列,和);
如果(列+1<列)
ans[2]=计算(行、列+1、和);
如果(列1>=0)
ans[3]=计算值(行、列1、和);
isMarked[row][col]=假;
返回std::min(std::min(ans[0],ans[1]),std::min(ans[2],ans[3]);
}
int main(){
标准::ifstream fin(“总和”);
fin>>行>>列;
对于(int i=0;i>网格[i][j];
int ans=计算值(0,0,0);
标准:流式输出(“求和”);
fout可能是这样的:
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]));
}
int计算(int行、int列、int和){
如果(标记为[行][列])
返回INT32_MAX;
if(行==行-1&&col==列-1)
返回和+网格[行][列];
isMarked[row][col]=真;
int ans[4]={INT32_MAX,INT32_MAX,INT32_MAX,INT32_MAX};
如果(第1行>=0)
ans[0]=计算(第1行,列,和+网格[行][col]);
如果(行+1<行)
ans[1]=计算(行+1,列,和+网格[行][列]);
如果(列+1<列)
ans[2]=计算(行、列+1、和+网格[行][col]);
如果(列1>=0)
ans[3]=计算(行,列-1,和+网格[行][列]);
isMarked[row][col]=假;
返回std::min(std::min(ans[0],ans[1]),std::min(ans[2],ans[3]);
}
使用调试器逐行检查代码时,您观察到了什么?我没有使用调试器,但我使用打印语句进行了大量测试。似乎大多数路径末端都是已标记的正方形,这是有意义的。所有到达末端的路径似乎都返回215,而正确的答案应该是87。使用调试器。无论是否设置了这些值,您都将取4件事的min
(a[0]、a[1]、a[2]、a[3]
),谢谢!我能够利用您的观察结果解决我的问题!