LeetCode174. Dungeon Game

LeetCode174. Dungeon Game

问题来源LeetCode174 Dungeon Game

问题描述

The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.

The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.

Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0’s) or contain magic orbs that increase the knight’s health (positive integers).

In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.

Write a function to determine the knight’s minimum initial health so that he is able to rescue the princess.

For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

-2(k)-33
-5101
1030-5(p)

问题分析

这道题算是一个RPG游戏的问题,就是骑士从左上角的方格开始取营救公主,中间会扣血(方格内为-X),或者加血(X),骑士最少的血量为1血。问骑士的最少初始血量是多少。

这道题又是一道动态规划的题目,但是这道题是用右下角向左上角计算的过程。计算骑士到达公主单元格的时候,所需要的血量。也就是dp[i][j]=1-dungeon[i][j],但是骑士到达其他单元格所需要的血量应该是
dp[i][j]=Math.max(Math.min(dp[i][j+1],dp[i+1][j])-dungeon[i][j],1);
也就是该单元格右侧和下册单元格所需要的最少血量加上当前单元格会照成的伤害。递归公式也就是这一下。剩下的就是进行代码的编写了。

Java代码


public int calculateMinimumHP(int[][] dungeon) {
    int m = dungeon.length;
    int n = dungeon[0].length;
    //利用动态规划保存记录
    int [][] dp = new int[m][n];
    //关键点就是从后往前遍历,首先记录最后个位置需要保证多少血,骑士血最少为1,所以与1进行比较,取最大值
    dp[m-1][n-1]=Math.max(-dungeon[m-1][n-1]+1,1);
    for (int i = n-2; i >=0; i--) {
        dp[m-1][i] = Math.max(dp[m-1][i+1]-dungeon[m-1][i],1);
    }
    for (int i = m-2; i >=0; i--) {
        dp[i][n-1]=Math.max(dp[i+1][n-1]-dungeon[i][n-1],1);
    }
    for (int i = m-2; i >=0 ; i--) {
        for(int j = n-2;j>=0;j--){
            dp[i][j]=Math.max(Math.min(dp[i][j+1],dp[i+1][j])-dungeon[i][j],1);
        }
    }
    return dp[0][0];
}

LeetCode学习笔记持续更新

GitHub地址 https://github.com/yanqinghe/leetcode

CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值