LeetCode931. Minimum Falling Path Sum最小下降路径和(动态规划,深度优先搜索)
题目描述
思路一:动态规划
最小下降和问题要求从第一行(r=0)的任何一个数开始,在下一行中再取一个数,要求列数与上一行选择的数的列数相差不超过一。
可以用动态规划的思想考虑这个问题,dp(r,c)为从A[r][c]这个数开始的最小下降路径和,可以看出:
dp(r,c)=A[r][c]+min{dp(r+1,j-1),dp(r+1,j),dp(r+1,j+1)}
最后的解即为min{dp[0][c]},0≤c<A.size()
为了避免开设新的空间来存储dp[r][c],直接利用原有的二维数组A。此时A的最后一行即为dp的最后一行,故从倒数第二行开始构建dp。
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& A) {
int len=A.size();
for(int i=len-2;i>=0;i--)
{
for(int j=0;j<len;j++)
{
int min_num=A[i+1][j];
if(j>0)min_num=min(A[i+1][j-1],min_num);
if(j+1<len)min_num=min(A[i+1][j+1],min_num);
A[i][j]+=min_num;
}
}
int ans=A[0][0];
for(int x:A[0])
{
if(x<ans)ans=x;
}
return ans;
}
};
思路二:深度优先搜索+记忆数组
class Solution {
public:
//DFS+MEMORIZATION
int dfs(vector<vector<int>>& A,vector<vector<int>>& mem,int i,int j)
{
if(i==A.size()-1)return A[i][j];
if(mem[i][j]!=INT_MAX)return mem[i][j];
int min_num=dfs(A,mem,i+1,j);
if(j>0)min_num=min(min_num,dfs(A,mem,i+1,j-1));
if(j+1<A.size())min_num=min(min_num,dfs(A,mem,i+1,j+1));
mem[i][j]=min_num+A[i][j];
return mem[i][j];
}
int minFallingPathSum(vector<vector<int>>& A) {
int len=A.size(),ans=INT_MAX;
vector<vector<int>>mem(len,vector<int>(len,INT_MAX));
for(int i=0;i<len;i++)
{
ans=min(ans,dfs(A,mem,0,i));
}
return ans;
}
};