程序员代码面试指南刷题--第四章.龙与地下城游戏问题

题目描述
给定一个二维数组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];
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值