日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[中等]

【解答思路】

1. 回溯(暴力)& 優化


超時,需要優化

public int calculateMinimumHP(int[][] dungeon) {if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) {return 0;}int rowLen = dungeon.length;int colLen = dungeon[0].length;// 最低的耗血量為 + 1;就是騎士的救公主的最低血量。return dfs(0, 0, rowLen, colLen, dungeon) + 1; }public int dfs (int rowIndex, int colIndex, int rowSize, int colSize, int[][] dungeon) {//if (rowIndex >= rowSize || colIndex >= colSize) {return Integer.MAX_VALUE;}// 退出條件if (rowIndex == rowSize - 1 && colIndex == colSize - 1) {if (dungeon[rowIndex][colIndex] >= 0) {// 如果最后一個大于等于0,就返還0。return 0;} else {//如果最后一個小于零,就返回負的值。return -dungeon[rowIndex][colIndex];}} // 右邊格子的最優解,也就是最低的耗血量int rightMin = dfs(rowIndex, colIndex + 1, rowSize, colSize, dungeon); // 下邊格子的最優解int downMin = dfs(rowIndex + 1, colIndex, rowSize, colSize, dungeon);// f(i,j) = min(f(i+1, j), f(i, j+1)) - dungeon[i][j]int needMin = Math.min(rightMin, downMin) - dungeon[rowIndex][colIndex];int res = 0;if (needMin < 0) {res = 0;} else {res = needMin;}System.out.println(rowIndex+ " "+colIndex + " " + res);return res; }作者:fakerleet 鏈接:https://leetcode-cn.com/problems/dungeon-game/solution/cong-hui-su-dao-ji-yi-hua-sou-suo-dao-dong-tai-gui/

private int rowSize = 0; private int colSize = 0; private int[][] globalDun = null; public int calculateMinimumHP(int[][] dungeon) {if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) {return 0;}rowSize = dungeon.length;colSize = dungeon[0].length;globalDun = dungeon;int[][] memory = new int[rowSize][colSize];// 初始化為-1,便于區別是否計算過結果了。for (int i = 0; i < rowSize; ++i) {for (int j = 0; j < colSize; ++j) {memory[i][j] = -1;}}return dfs(0, 0, memory) + 1; }public int dfs (int rowIndex, int colIndex, int[][] memory) {if (rowIndex >= rowSize || colIndex >= colSize) {return Integer.MAX_VALUE;}// 不為-1就是計算過了,直接返回結果。if (memory[rowIndex][colIndex] != -1) {return memory[rowIndex][colIndex];}if (rowIndex == rowSize - 1 && colIndex == colSize - 1) {if (globalDun[rowIndex][colIndex] >= 0) {return 0;} else {return -globalDun[rowIndex][colIndex];}}int right = dfs(rowIndex, colIndex + 1, memory);int down = dfs(rowIndex + 1, colIndex, memory);int needMin = Math.min(right, down) - globalDun[rowIndex][colIndex];int res = 0;if (needMin < 0) {res = 0;} else {res = needMin;}memory[rowIndex][colIndex] = res;System.out.println(rowIndex+ " "+colIndex + " " + res);return res; }作者:fakerleet 鏈接:https://leetcode-cn.com/problems/dungeon-game/solution/cong-hui-su-dao-ji-yi-hua-sou-suo-dao-dong-tai-gui/
2. 動態規劃

思路一:緊接上文
問:深搜過程中的記憶化,真的能保證走過的路徑是最優的嗎?比如第一次搜索經過[2,2]這個點,把結果記錄下來。下次再次搜索的時候,起點可能不一樣了,這個時候有沒有可能計算結果對[2,2]產生更新呢?
答:dfs的遞歸本身就是逆推的
第一次搜索[2,2] 看起來是第一次搜索 其實已經是右和下方的回滾了

public int calculateMinimumHPBest(int[][] dungeon) {if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) {return 0;}int rowSize = dungeon.length;int colSize = dungeon[0].length;int[][] dp = new int[rowSize][colSize];// 設置最后一個值。dp[rowSize - 1][colSize -1] = Math.max(0, -dungeon[rowSize - 1][colSize - 1]);// 設置最后一列的值for (int i = rowSize - 2; i >= 0; --i) {int needMin = dp[i + 1][colSize - 1] - dungeon[i][colSize - 1];dp[i][colSize -1] = Math.max(0, needMin);}// 設置最后一行的值for (int i = colSize - 2; i >= 0; --i) {int needMin = dp[rowSize - 1][i + 1] - dungeon[rowSize - 1][i];dp[rowSize - 1][i] = Math.max(0, needMin);}for (int i = rowSize - 2; i >= 0; --i) {for (int j = colSize - 2; j >= 0; --j) {// 從右邊和下邊選擇一個最小值,然后減去當前的 dungeon 值int needMin = Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];dp[i][j] = Math.max(0, needMin);}}return dp[0][0] + 1; }作者:fakerleet 鏈接:https://leetcode-cn.com/problems/dungeon-game/solution/cong-hui-su-dao-ji-yi-hua-sou-suo-dao-dong-tai-gui/

思路二:

class Solution {public int calculateMinimumHP(int[][] dungeon) {int n = dungeon.length, m = dungeon[0].length;int[][] dp = new int[n + 1][m + 1];for (int i = 0; i <= n; ++i) {Arrays.fill(dp[i], Integer.MAX_VALUE);}dp[n][m - 1] = dp[n - 1][m] = 1;for (int i = n - 1; i >= 0; --i) {for (int j = m - 1; j >= 0; --j) {int minn = Math.min(dp[i + 1][j], dp[i][j + 1]);dp[i][j] = Math.max(minn - dungeon[i][j], 1);}}return dp[0][0];} }作者:LeetCode-Solution 鏈接:https://leetcode-cn.com/problems/dungeon-game/solution/di-xia-cheng-you-xi-by-leetcode-solution/

【總結】

1. 動態規劃流程

第 1 步:設計狀態
第 2 步:狀態轉移方程
第 3 步:考慮初始化
第 4 步:考慮輸出
第 5 步:考慮是否可以狀態壓縮

2.思路 DFS -> 記憶化DFS->動態規劃

轉載:https://leetcode-cn.com/problems/dungeon-game/solution/cong-hui-su-dao-ji-yi-hua-sou-suo-dao-dong-tai-gui/
參考:https://leetcode-cn.com/problems/dungeon-game/solution/di-xia-cheng-you-xi-by-leetcode-solution/

總結

以上是生活随笔為你收集整理的[Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。