题目
黄金圣斗士拯救雅典娜,雅典娜在右下角
- 每次只能往右边或者下面走,每个位置的值代表遭遇的事件,如果是负数则扣血
- 如果是正数则回血,走到任何一个位置,血量都不能少于1,为了保证救出雅典娜,
- 初始血量至少是多少?
输入
-2 -3 3
-5 -10 1
0 30 -5
解析
这是一道动态规划的题目,可以考虑倒着使用dp。因为少于一点血就会死亡,所以有
dp[i][j]] >= 1 && ( dp[i][j]+map[i][j]>=dp[i+1][j] || dp[i][j]+map[i][j]>=dp[i][j+1] )
上面的||是二者取其一即可,因为要求的是初始血量的最小值。
因为是倒着使用的,所以后面的是已知的。 现在看一下初始条件,初始条件即骑士走完map[i][j]之后血量仍然要>=1, 这样可以得到初始条件
dp[n-1][m-1] >= 1 && dp[n-1][m-1]+map[n-1][m-1]>=1
代码如下(java)
public int getMin(int n, int m, int[][] map) {
if (map == null || n == 0 || m == 0) return 1;
int[][] dp = new int[n][m];
for(int i = n-1;i>=0;i--) {
for(int j = m-1;j>=0;j--) {
if(i==n-1 && j==m-1)
dp[i][j] = Math.max(1,1-map[i][j]);
else if(i==n-1)
dp[i][j] = Math.max(1,dp[i][j+1]-map[i][j]);
else if(j==m-1)
dp[i][j] = Math.max(1,dp[i+1][j]-map[i][j]);
else
dp[i][j] = Math.min(Math.max(1,dp[i+1][j]-map[i][j]), Math.max(1,dp[i][j+1]-map[i][j]));
}
}
return dp[0][0];
}