174.Dungeon Game---dp
题目大意:从左上角到右下角,每一个格子都有各自的权值,如果权值为负,则当到达时,要失血;如果权值为正,则当到达时,要加血。当到达某个格子时,当前血量<=0,则死亡,到达不了右下角,所以此时要计算从左上角到右下角,初始应该最少携带多少血(即经过所有路径后所计算出的值),才不会死亡,能正常到达右下角。
法一:dfs,模板深搜,果断超时。要注意:更新点不是整条路径的和(与64题比较)的最小值,而是整条路径中所达到的最大的失血量,如果最大失血量>=0,则本身只需要携带1个血即可;否则本身携带的血应该=abs(最大失血量)+1。代码如下:
public int calculatedMinimumHP(int[][] dungeon) {
boolean vis[][] = new boolean[dungeon.length][dungeon[0].length];
int f[][] = {{1, 0}, {0, 1}};
vis[0][0] = false;
return dfs(dungeon, 0, 0, dungeon[0][0], Integer.MAX_VALUE, dungeon[0][0], vis, f);
}
public int dfs(int[][] dungeon, int x, int y, int sum, int res, int blood, boolean vis[][], int f[][]) {
if(x == dungeon.length - 1 && y == dungeon[0].length - 1) {
//递归结束点是每条线路的过程中的最大失血量
if(blood < 0) {//如果失血量为负数,则是绝对值+1
if(Math.abs(blood) < res) {
res = Math.abs(blood) + 1;
}
}
else {//如果失血量>=0,则是1,因为当失血量为0时,也会死亡
res = 1;
}
return res;
}
for(int i = 0; i < 2; i++) {
int cnt_x = x + f[i][0];
int cnt_y = y + f[i][1];
if(cnt_x < dungeon.length && cnt_y < dungeon[0].length && vis[cnt_x][cnt_y] == false) {
vis[cnt_x][cnt_y] = true;
res = dfs(dungeon, cnt_x, cnt_y, sum + dungeon[cnt_x][cnt_y], res, blood < (sum + dungeon[cnt_x][cnt_y]) ? blood : (sum + dungeon[cnt_x][cnt_y]), vis, f);
vis[cnt_x][cnt_y] = false;
}
}
return res;
}
法二(借鉴):dp,类似于64的二维dp,64是从左上往右下,而这题是从右下往左上。dp[i][j]表示从坐标[i,j]到右下角的路径中需要的最少血量,这样每次计算时,都可以用到下面和右面的dp值,从中取最小再将当前值减去即可。其中要追的地方与dfs相似,在每一个格子中,都要始终保持至少1个血量。dp公式:dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - du[i][j]。代码如下(耗时2ms):
public int calculatedMinimumHP(int[][] dungeon) {
int dp[][] = new int[dungeon.length][dungeon[0].length];
//初始化最后一列
//由于走到每个格子时,都要保持至少一个血量,所以应该用到max(1, ...)
dp[dungeon.length - 1][dungeon[0].length - 1] = Math.max(1, 1 - dungeon[dungeon.length - 1][dungeon[0].length - 1]);
for(int i = dungeon.length - 2; i >= 0; i--) {
dp[i][dungeon[0].length - 1] = Math.max(1, dp[i + 1][dungeon[0].length - 1] - dungeon[i][dungeon[0].length - 1]);
}
//初始化最后一行
for(int i = dungeon[0].length - 2; i >= 0; i--) {
dp[dungeon.length - 1][i] = Math.max(1, dp[dungeon.length - 1][i + 1] - dungeon[dungeon.length - 1][i]);
}
//计算dp
for(int i = dungeon.length - 2; i >= 0; i--) {
for(int j = dungeon[0].length - 2; j >= 0; j--) {
//从下边和右边中取出最小者,然后减去当前值
dp[i][j] = Math.max(1, Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]);
}
}
return dp[0][0];
}
174.Dungeon Game---dp的更多相关文章
- Java for LeetCode 174 Dungeon Game
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- leetcode@ [174] Dungeon Game (Dynamic Programming)
https://leetcode.com/problems/dungeon-game/ The demons had captured the princess (P) and imprisoned ...
- [LeetCode] 174. Dungeon Game 地牢游戏
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- ✡ leetcode 174. Dungeon Game 地牢游戏 --------- java
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- 174. Dungeon Game
题目: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dung ...
- 174. Dungeon Game(动态规划)
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- [leetcode]174. Dungeon Game地牢游戏
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- LeetCode 174. Dungeon Game (C++)
题目: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dung ...
- 174 Dungeon Game 地下城游戏
一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格布局.我们英勇的骑士(K)最初被安置在左上角的房间里,并且必须通过地下城对抗来拯救公主.骑士具有以正整数 ...
随机推荐
- [COCI2011-2012#5] POPLOCAVANJE 后缀自动机
题面:洛谷 题解: 其实还可以用AC自动机做,但是没调出来,,,不知道发生了什么... AC自动机做法如下: 观察到如果我们对给定的每个串建AC自动机,那么直接拿大串在上面匹配,如果遇到了一个单词的终 ...
- Linux学习笔记二:Ubuntu安装SSH(Secure Shell)服务
Ubuntu默认是没有安装SSH(Secure Shell)服务,如果想要通过ssh链接到Ubuntu,我们需要手动安装ssh-server. SSH分客户端ssh-client,服务端ssh-ser ...
- 【JavaScript】BOM
一.前言 接着前一章的内容,继续Js的学习. 二.内容 window对象 //确定窗口位置 var leftPos = (typeof window.screenLeft == &quo ...
- 【MediaElement】WPF视频播放器【1】
一.前言 前两天上峰要求做一个软件使用向导,使用WPF制作.这不,这两天从一张白纸开始学起,做一个播放演示视频的使用向导.以下是粗设计的原型代码: 二.效果图 三.代码 前台代码: < ...
- 使用SetupDI* API列举系统中的设备
原文链接地址:https://blog.csdn.net/clteng/article/details/801012?utm_source=blogxgwz8 在Windows系统中提供一组有用的函数 ...
- 【agc017E】Jigsaw
Portal -->agc017 Description 给你\(n\)块积木,每块积木由三个矩形组成,中间的矩形最高高度为\(h\),左边的矩形高度为\(a_i\)离底边高度为\(c_i\), ...
- LOJ #6036.「雅礼集训 2017 Day4」编码 Trie树上2-sat
记得之前做过几道2-sat裸体,以及几道2-sat前缀优化建图,这道题使用了前缀树上前缀树优化建图.我们暴力建图肯定是n^2级别的,那么我们要是想让边数少点,就得使用一些骚操作.我们观察我们的限制条件 ...
- Jenkins CI Pipeline scripting
Jenkins pipeline is a suite of Jenkins plugins. Pipelines can be seen as a sequence of stages to per ...
- 二叉树系列 - 求两节点的最低公共祖先,例 剑指Offer 50
前言 本篇是对二叉树系列中求最低公共祖先类题目的讨论. 题目 对于给定二叉树,输入两个树节点,求它们的最低公共祖先. 思考:这其实并不单单是一道题目,解题的过程中,要先弄清楚这棵二叉树有没有一些特殊的 ...
- 用CSS3画出一个立方体---转
css3实践—创建3D立方体 要想实现3D的效果,其实非常简单,只需指定一个元素为容器并设置transform-style:preserve-3d,那么它的后代元素便会有3D效果.不过有很多需要注意的 ...