拯救雅典娜

题目

黄金圣斗士拯救雅典娜,雅典娜在右下角

  • 每次只能往右边或者下面走,每个位置的值代表遭遇的事件,如果是负数则扣血
  • 如果是正数则回血,走到任何一个位置,血量都不能少于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];
   }

你可能感兴趣的:(动态规划)