[LeetCode] Minimum Falling Path Sum

首先这篇博客本来在11月11日晚上就该发出来的。但是当时的我在图书馆,突然电脑抽风无线网络死活连不上,本来打算回到宿舍就把它发出来,可是回到宿舍之后忘记了。。因为回宿舍的路上发生了一点点事情。

1、题目

Given a square array of integers A, we want the minimum sum of a falling path through A.

A falling path starts at any element in the first row, and chooses one element from each row.  The next row's choice must be in a column that is different from the previous row's column by at most one.

Example 1:

Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: 12
Explanation: 
The possible falling paths are:
  • [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
  • [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
  • [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]

The falling path with the smallest sum is [1,4,7], so the answer is 12.

2、分析

实际上求最大值或者最小值算是十分十分经典的动态规划算法了。在已知最值的基础上建立新情况下的最值。这里要求的是从第一行到达最后一行的最小值。每次能够往下移动一行,但是列数相差最多为1。比如从位置(0,0)只能移动到(1,0)或者(1,1),从位置(0,1)可以移动到(1,0)(1,1)或者(1,2)。动态规划思路很简单:创建一个二维数组dp,dp[i][j]表示到达位置(i,j)所需要的最小步数,题目要求的是到达最后一行的最小步数,那么结果就是dp数组最后一行的最小值。dp数组的第一行的值和题目给出的数组一样。从第二行开始:dp[i][j] = A[i][j]+min(能够到达A[i][j]的前三个位置)。比如:

dp[1][1] = A[1][1]+min(dp[0][0],dp[0][1],dp[0][2])。边界条件自己写代码的时候注意一下就好了。到达此位置的最小步数 = 从前一步移动到此位置的步数+到达前一步的最小步数。

3、代码

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& A) {
        int m = A.size();
        int n = A[0].size();
        int dp[m][n]={0};
        int mini = 0;
        for(int i=0;i<m;i++)
            mini+=A[i][0];
        for(int i=0;i<n;i++)
            dp[0][i] = A[0][i];
        for(int i=1;i<m;i++)
            for(int j=0;j<n;j++)
            {
                dp[i][j] = A[i][j]+min(dp[i-1][j-1<0?0:j-1],min(dp[i-1][j],dp[i-1][j+1>=n?n-1:j+1]));
                if(i==m-1&&dp[i][j]<mini) mini = dp[i][j];
            }
        return mini;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36303832/article/details/84036059