天题系列: 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) -3 3
-5 -10 1
10 30 -5 (P)

Notes:

    • The knight‘s health has no upper bound.
    • Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.

要是玩还挺来劲的,想怎做可就费劲了。

ref 思路和code来自http://blog.csdn.net/yangliuy/article/details/42643265

下面是抄人家的思路

“思路分析:这题容易想到的思路是用search DFS或者BFS解,给定起点和终点,我们可以搜索所有从起点到终点的路径,然后贪心保存下来最小的路径权值之和,同时要保证每次扩展分支时当前的生命值状态始终大于0。但是这并不是好的解法,时间复杂度太高。实际上,这题和Unique Path很相似,都是从左上角走到右下角,并且每个格子只能向下或者向右,也就是每个格子只有右边或者下边两个相邻格子。我们可以考虑用动态规划解。关键是如何定义dp数组,这题和Unique Path中dp数组的定义相比有点不同。假设给定的网格是m*n维,我们需要定义dp[][]表示从(i,j)到终点(m-1,n-1)需要的最小生命值,那么递推方程为dp[i][j] = max(min(dp[i][j+1], dp[i+1][j]) - dungeon[i][j], 0),如果dungeon[i][j]为正,则减去一个正数,初始需要的生命值变小。同理可以理解dungeon[i][j]为负数的情况。和0取最大保证了初始生命值为非负。代码实现很简单,就是初始化后自下而上自右向左填表,典型的二维DP问题的做法。关于这类网格图论问题可以用DFS,BFS,DP以及经典的图算法比如dijkstra 算法,flod算法等等来做,需要多做做这类题目,根据不同情况选择不同算法,增加做这类题目的经验。”

最后返回值+1,比如 input [[0]]

public class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length;
        int n = dungeon[0].length;
        int[][] dp = new int[m][n];
        dp[m-1][n-1] = Math.max(0, 0-dungeon[m-1][n-1]);
        for(int i=m-2;i>=0;i--){
            dp[i][n-1] = Math.max(0,dp[i+1][n-1]-dungeon[i][n-1]);
        }
        for(int j=n-2;j>=0;j--){
            dp[m-1][j] = Math.max(0,dp[m-1][j+1]-dungeon[m-1][j]);
        }
        for(int i=m-2;i>=0;i--){
            for(int j=n-2;j>=0;j--){
                dp[i][j] = Math.max(0,Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
            }
        }
        return dp[0][0]+1;
    }
}
时间: 2024-11-24 16:55:38

天题系列: Dungeon Game的相关文章

微软100题系列之-----设计包含min函数的栈

题意: 定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素. 要求函数min.push 以及pop 的时间复杂度都是O(1). 思路:定义两个栈,一个用来记录数据的插入和删除,一个用来存储最小值的变化 代码如下: template <class T> class Stack { public: Stack(int len=100); T Min(); T Pop(); void Push(T val); private: T top1,top2; T *stack1,*stack

软考培训 | 根据2016新教程改版的百题系列完成改版工作

攻克要塞之考前100题系列完成改变工作. 两本书籍,<攻克要塞百题系列 系统集成项目管理工程师考前冲刺100题 第二版> <攻克要塞百题系列 信息系统项目管理师考前冲刺100题> 其中,中级系列用书根据2016新版教程和考纲进行了内容调整. 预计9月底上市发行! 本书配套的视频将于下半年在51cto视频网站发行.

微软面试100题系列算法心得

微软100题系列地址 答案地址 谓之随笔,当是自己在练习此类算法的一些想法,一些心得,一些领悟,一些借鉴,当自引用之时,会附上相应的链接! 题:把二元查找树转变成排序的双向链表(树) 描述:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 思维过程[个人思维]: 1. 二元查找树是指在任何结点看来,它的左子树上的值要少于当前结点的值,而它的右子树上的值要大于当前结点的值,对于等于的值那就看自己的原则放左子树还是右子树. 2. 关于树的算法必

hdu5017:补题系列之西安网络赛1011

补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为min(a,b,c) 所以我们需要把原方程化为标准型. 这时候线代就排上用场了,注意到原方程是一个二次型. 化为标准型 1/(k1)*x^2+1/(k2)*y^2+1/(k3)*z^2=1 后  min(k1,k2,k3)即为答案 而这里的1/k1,1/k2,1/k3 就是二次型矩阵的特征值 如何求特

ACdream oj C - 神奇的%系列一 (水题系列--略坑)

 C - 神奇的%系列一 Time Limit: 6000/3000 MS (Java/Others)      Memory Limit: 65536/32768 KB (Java/Others) Submit Status Problem Description 在计算机的世界里,%不是百分比,而是除法取余哟! 比如: 4 % 2 = 0 5 % 3 = 2 给你 2<=N<=100000 个数,a[1],a[2]...a[i]...a[n]. 其中:1<=a[i]<=10

nyoj 1208——水题系列——————【dp】

水题系列 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述     给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权值大的情况下,问你最多能走几条边? 输入 首先一个n和m,分别表示点的数目和边的数目接下来m行,每行三个值x,y,val,表示x到y有路,其权值为val.(1<n,m,val<10^5,0<x,y<=n) 输出 输出最多有的边的数目 样例输入 3 3 1 2 1 2 3 1 3 1 1 6

LCT男人八题系列

楼教的男人八题名气甚大,今天做了一道感觉还是涨了不少姿势的,然而估计之后的每道题都要看题解吧,姑且先记录一下.以后再做再更 1737 Connected Graph 1100 [email protected] 1738 An old Stone Game 407 [email protected] 1739 Tony's Tour 671 [email protected] 1740 A New Stone Game 2240 [email protected] 1741 Tree 1728

微软面试100题系列:字符串匹配算法,查找包含字符集的子串

觉得这题挺有意思,看了别的博客,找到了一种目前看来还不错的算法,为强化理解,就写了下来. 题目意思: 实现一个挺高级的字符匹配算法: 给一串字符串,要求找到符合要求的字符串,例如对于目的串:123,那么给定字符串中诸如1******3*****2,12******3这些形式的子串都要找出来,即子串中含有目的串的所有字符,输出所有符合条件的字符串,并求出最短子串 .类似于和谐系统. 例如:假如目的串为:"423",输入长字符串为:"4fsdfk2jfl3fd2jfksd3j4d

天题系列: LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.set(