题目链接

题目大意:从左上角到右下角,每一个格子都有各自的权值,如果权值为负,则当到达时,要失血;如果权值为正,则当到达时,要加血。当到达某个格子时,当前血量<=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的更多相关文章

  1. Java for LeetCode 174 Dungeon Game

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  2. leetcode@ [174] Dungeon Game (Dynamic Programming)

    https://leetcode.com/problems/dungeon-game/ The demons had captured the princess (P) and imprisoned ...

  3. [LeetCode] 174. Dungeon Game 地牢游戏

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  4. ✡ leetcode 174. Dungeon Game 地牢游戏 --------- java

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  5. 174. Dungeon Game

    题目: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dung ...

  6. 174. Dungeon Game(动态规划)

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  7. [leetcode]174. Dungeon Game地牢游戏

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  8. LeetCode 174. Dungeon Game (C++)

    题目: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dung ...

  9. 174 Dungeon Game 地下城游戏

    一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格布局.我们英勇的骑士(K)最初被安置在左上角的房间里,并且必须通过地下城对抗来拯救公主.骑士具有以正整数 ...

随机推荐

  1. 【数据库_Mysql】查询当前年份的sql

    1.本年份 SELECT DATE_FORMAT(NOW(), '%Y'); 2.本月份(显示数字) SELECT DATE_FORMAT(NOW(), '%m'); 3.本月份(显示英文) SELE ...

  2. [一]SpringBoot 之 HelloWorld

    (1)新建一个Maven Java工程 (2)在pom.xml文件中添加Spring BootMaven依赖 2.1在pom.xml中引入spring-boot-start-parent spring ...

  3. [BZOJ4870][Shoi2017]组合数问题 dp+矩阵乘

    4870: [Shoi2017]组合数问题 Time Limit: 10 Sec  Memory Limit: 512 MB Description Input 第一行有四个整数 n, p, k, r ...

  4. 把lighttpd配置为系统服务

    每次启动切换到 /usr/local/lighttpd/sbin 执行 ./lighttpd -f /usr/local/lighttpd/lighttpd.conf 比较麻烦, 而且不方便重新启动! ...

  5. 解题:POI 2009 TAB

    题面 这也算是个套路题(算吗)?发现换来换去每行每列数的组成是不变的,那么就把每行每列拎出来哈希一下,复杂度$O(Tn^2log$ $n)$有点卡时=.=. 然而正解似乎不需要哈希,就像这样↓ ;i& ...

  6. 【poj2068】Nim

    Portal -->poj2068 Description ​  给你\(S\)个石子,有\(2n\)个人分成两队,编号为奇数的一队,编号为偶数的一队,\(2n\)个人按照编号从小到大的顺序拿石 ...

  7. Ciesz się Polską

    SZKOpułPoi at BZOJPA at BZOJONTAK at BZOJ Chinese Solution of Poi

  8. 防止apk反编译的技术分析浅谈--内存修改器篇

    声明: 1.本帖转载自http://jingyan.baidu.com/article/a24b33cd509eb719fe002b94.html,仅供自用,勿喷 Apk反编译修改器有很多.拿其中的比 ...

  9. packet32 -- 打印packet32捕获的包

    void PrintPackets(LPPACKET lpPacket) { ULONG i, j, ulLines, ulen, ulBytesReceived; char *pChar, *pLi ...

  10. java多线程机制1(线程创建的两种方式)

    进程:正在运行的程序.(即程序在内存中开辟了一片空间) 线程:是进程的执行单元. 一个进程至少包含了一个多个线程. 多线程是不是可以提高效率:多线程可以合理的利用系统的资源,提高效率是相对的.因为cp ...