直觉从这个DP的右下角(而不是左上角)开始

时间:2017-11-16 16:39:51

标签: c++ algorithm dynamic-programming

我在LeetCode上解决Dungeon Game。虽然我能够提出递归关系(并且首先确定它是一个DP问题),从右下角开始的直觉是什么,如高度支持的解决方案所示:

class Solution {
public:
    int calculateMinimumHP(vector<vector<int> > &dungeon) {
        int M = dungeon.size();
        int N = dungeon[0].size();
        // hp[i][j] represents the min hp needed at position (i, j)
        // Add dummy row and column at bottom and right side
        vector<vector<int> > hp(M + 1, vector<int>(N + 1, INT_MAX));
        hp[M][N - 1] = 1;
        hp[M - 1][N] = 1;
        for (int i = M - 1; i >= 0; i--) {
            for (int j = N - 1; j >= 0; j--) {
                int need = min(hp[i + 1][j], hp[i][j + 1]) - dungeon[i][j];
                hp[i][j] = need <= 0 ? 1 : need;
            }
        }
        return hp[0][0];
    }
};

我认为它与Unique Paths问题非常相似,因此从左上角开始求解(但它没有检索到正确的结果)。我的解决方案(如果需要的话)是:

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        if(dungeon==null || dungeon.length==0 || dungeon[0]==null || dungeon[0].length==0)
            return -1;

        int maxVal = 0;
        int[][] dp = new int[dungeon.length][dungeon[0].length];
        dp[0][0] = dungeon[0][0];
        for(int i=1; i<dungeon.length; i++)
            dp[i][0] = dp[i-1][0] + dungeon[i][0];
        for(int i=1; i<dungeon[0].length; i++)
            dp[0][i] = dp[0][i-1] + dungeon[0][i];

        int chosenOne=0;
        for(int i=1; i<dungeon.length; i++) {
            for(int j=1; j<dungeon[0].length; j++) {
                if(dp[i-1][j] < 0 && dp[i][j-1] < 0) {
                    chosenOne = Math.max(dp[i-1][j], dp[i][j-1]);
                }
                else {
                    if(dp[i-1][j] > 0 && dp[i][j-1] > 0) {
                        chosenOne = Math.min(dp[i-1][j], dp[i][j-1]);
                    }
                    else {
                        chosenOne = (dp[i-1][j]>0?dp[i-1][j]:dp[i][j-1]);
                    }
                }
                dp[i][j] = dungeon[i][j] + chosenOne;
                maxVal = Math.min(maxVal, dp[i][j]);
            }
        }

        return maxVal+1;
    }
}

其中一条评论here by 'JaiMataDi'提到它是因为我们不知道骑士的最初健康点。但是 I 使用的方法怎么样?

确切地说,有人可以指出为什么我们从右下角而不是左上角开始的直觉?

谢谢!

0 个答案:

没有答案