题目描述
给定一个二维数组map,含义是一张地图
游戏的规则如下:
1)骑士从左上角出发,每次只能向右或向下走,最后到达右下角见到公主。
2)地图中每个位置的值代表骑士要遭遇的事情。如果是负数,说明此处有怪兽,要让骑士损失血量。如果是非负数,代表此处有血瓶,能让骑士回血。
3)骑士从左上角到右下角的过程中,走到任何一个位置时,血量都不能少于1。为了保证骑土能见到公主,初始血量至少是多少?
根据map,输出初始血量。
输入描述:
第一行两个正整数n,m,接下来n行,每行m个整数,代表
输出描述:
输出一个整数,表示答案。
示例1
输入
3 3
-2 -3 3
-5 -10 1
0 30 -5
输出
7
示例2
输入
2 2
1 1
1 1
输出
1
解法一:自己写的(妈的为啥过不了)
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int n = Integer.parseInt(info[0]);
int m = Integer.parseInt(info[1]);
int[][] arr = new int[n][m];
for(int i=0;i<n;i++){
String[] tmp = br.readLine().trim().split(" ");
for(int j=0;j<m;j++){
arr[i][j] = Integer.parseInt(tmp[j]);
}
}
int res = getMin(arr,n,m);
System.out.println(res);
}
public static int getMin(int[][] arr,int n,int m){
if(n==0||m==0) return 1;
Info[][] dp = new Info[n][m];
int need = arr[0][0]>=0?1:1-arr[0][0];
int blood = arr[0][0]>=0?1+arr[0][0]:1;
dp[0][0] = new Info(need,blood);
//处理第一行
for(int i=1;i<m;i++){
int preblood = dp[0][i-1].blood;
int preneed = dp[0][i-1].need;
Info info = null;
if(arr[0][i]>=0){
info = new Info(preneed,preblood+arr[0][i]);
}else if(preblood+arr[0][i]>0){
info = new Info(preneed,preblood+arr[0][i]);
}else{
int tmpneed = preneed-(preblood+arr[0][i])+1;
info = new Info(tmpneed,1);
}
dp[0][i] = info;
}
//处理第一列
for(int i=1;i<n;i++){
int preblood = dp[i-1][0].blood;
int preneed = dp[i-1][0].need;
Info info = null;
if(arr[i][0]>=0){
info = new Info(preneed,preblood+arr[i][0]);
}else if(preblood+arr[i][0]>0){
info = new Info(preneed,preblood+arr[i][0]);
}else{
int tmpneed = preneed-(preblood+arr[i][0])+1;
info = new Info(tmpneed,1);
}
dp[i][0] = info;
}
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
Info up = dp[i-1][j];
Info left = dp[i][j-1];
Info fromup = new Info(up.need,up.blood+arr[i][j]);
Info fromleft = new Info(left.need,left.blood+arr[i][j]);
Info tmp = null;
if(fromup.blood<=0){
fromup.need = 1-fromup.blood+fromup.need;
fromup.blood = 1;
}
if(fromleft.blood<=0){
fromleft.need = 1-fromleft.blood+fromleft.need;
fromleft.blood = 1;
}
if(fromleft.need<fromup.need){
tmp = fromleft;
}else if(fromleft.need>fromup.need){
tmp = fromup;
}else if(fromleft.blood>fromup.blood){
tmp = fromleft;
}else{
tmp = fromup;
}
dp[i][j] = tmp;
}
}
return dp[n-1][m-1].need;
}
}
class Info{
int need;
int blood;
public Info(int need,int blood){
this.need = need;
this.blood = blood;
}
}
解法二:哎我是笨逼
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int n = Integer.parseInt(info[0]);
int m = Integer.parseInt(info[1]);
int[][] arr = new int[n][m];
for(int i=0;i<n;i++){
String[] tmp = br.readLine().trim().split(" ");
for(int j=0;j<m;j++){
arr[i][j] = Integer.parseInt(tmp[j]);
}
}
int res = getMin(arr,n,m);
System.out.println(res);
}
public static int getMin(int[][] arr,int n,int m){
if(n==0||m==0) return 1;
int[][] dp = new int[n--][m--];
dp[n][m] = arr[n][m]>=0?1:1-arr[n][m];
for(int j=m-1;j>=0;j--){
dp[n][j] = Math.max(dp[n][j+1]-arr[n][j],1);
}
for(int i=n-1;i>=0;i--){
dp[i][m] = Math.max(dp[i+1][m]-arr[i][m],1);
for(int j=m-1;j>=0;j--){
int right = Math.max(dp[i][j+1]-arr[i][j],1);
int left = Math.max(dp[i+1][j]-arr[i][j],1);
dp[i][j] = Math.min(right,left);
}
}
return dp[0][0];
}
}