黃金聖鬥士歐洛斯要去聖域救雅典娜,需要從左上角出發,每次只能向右或向下走,最後到右下角見到雅典娜。地圖中每個位置代表聖鬥士遭遇的事情,如果是負數,說明此處有狙擊,要讓盛都歐式損失血量,如果是非負數,說明此處有血瓶,能讓聖鬥士回血,聖鬥士從左上角到右下角的過程中,走到任何一個位置是,血量都不能少於1,爲了保證聖鬥士能救出雅典娜,初始血量至少爲多少?地圖爲一個二維數組map,如下矩陣,根據map返回初始血量。
-2 -3 3
-5 -10 1
0 30 -5
返回7
思路是這樣的:
從左上角到右下角有n條路徑,求每條路徑上最大耗血量,這n個耗血量中的最小耗血量+1即爲初始血量。
因爲每一步都要求血量最少爲1,設初始血量爲-1,從map[0][0]到map[n][m]做加法,記錄這個累加過程中的最小值(一定是負數,且最大爲-1)。
到達map[n][m]的時候比較這條路徑的累加最小值min和以前的最大的累加最小值max,二者取大值存入max
最後所求血量即爲-1*max
import java.util.Scanner;
public class MyTest2 {
static int max=-1;
static boolean flag=true;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
int[][]map=new int[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
map[i][j]=sc.nextInt();
}
}
minblood(map,n-1,m-1,-1,0,0,-1);
int ans=-1*max;
System.out.println(ans);
}
private static void minblood(int[][] map,int n,int m,int curr,int midn,int midm,int min) {
curr=curr+map[midn][midm];
min=Math.min(min, curr);
if(midn==n&&midm<m){//到達行邊界未到列邊界
minblood(map,n,m,curr,midn,midm+1,min);
}else if(midm==m&&midn<n){ //到達列邊界未到行邊界
minblood(map,n,m,curr,midn+1,midm,min);
}else if(midn==n&&midm==m){//到行列邊界
if(flag){//第一次到達右下角
max=min;
flag=false;
}else{
max=Math.max(min,max);
}
}else{ //未到達邊界
minblood(map,n,m,curr,midn+1,midm,min);
minblood(map,n,m,curr,midn,midm+1,min);
}
}
}
/*
*
3 3
-2 -3 3 -5 -10 1 0 30 -5
3 3
0 -1 -1 0 -1 -1 0 0 0
2 2
1 1 1 1
2 2
-1 0 0 -1
*/