我在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 使用的方法怎么样?
确切地说,有人可以指出为什么我们从右下角而不是左上角开始的直觉?
谢谢!