第十三周(Dungeon Game)

来源:互联网 发布:云烟淘宝客鹊桥助手 编辑:程序博客网 时间:2024/06/05 18:24

第十三周(Dungeon Game)

目录:

  • 本周完成题目
  • 主要过程思路
  • 相关代码

一、本周完成题目

本周共完成2道题目,1道Hard,1道 Medium。

具体完成题目及难度如下表:

# Title Difficulty 63 Unique Paths II Medium 174 Dungeon Game Hard

题目内容

1、Unique Paths II 
Follow up for “Unique Paths”:
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as 1 and 0 respectively in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.

    [      [0,0,0],      [0,1,0],      [0,0,0]    ]

The total number of unique paths is 2.

题目大意:给定一个二维数组,数组中1代表不能访问,0代表可以访问,求从左上角到右下角共有多少种路径。

2、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)

题目大意:从左上角到右下角,按照路径加血或者减血,需要保证hp值始终大于0,求最少的总血量。

二、主要过程思路

1、Unique Paths II:

本题与unique path类似,但是在初始化的时候需要将每个格子置零。对于每个坐标为i,j的格子,要到达这个格子有两种路径。所以到达这个格子的路径数可以表示为:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 。设定i,j进行循环操作求出右下角即可。 但是在求的过程中需要判断是否为1,如果该格为1则不对该点进行操作,使之依然为0。

2、Dungeon Game:

本题的思路参考了https://segmentfault.com/a/1190000005711596 中的方法。
假设dp(i, j)是走完(i, j)后所剩余的血量(dp(i, j)肯定是大于等于1的)。如果想存活下来,最少需要dp(i, j) = dp(上一步血量)+ dungeon(i, j) >= 1,即:dp(i, j) = max(1, dp(上一步血量)- dungeon(i, j)). 然后分类讨论上一步血量的可能性,注意边界情况的初始化即可。具体而言需要先初始化右下角位置,之后对于边界进行初始化,最后从右下角开始往左上角回溯,最后返回dp[0][0]即可。

三、相关代码

Unique Paths II

class Solution {public:    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {        int m = obstacleGrid.size() , n = obstacleGrid[0].size();        vector<vector<int> > dp(m+1, vector<int> (n+1, 0));        dp[0][1] = 1;        for (int i = 1; i <= m; i++)            for (int j = 1; j <= n; j++)                if(obstacleGrid[i-1][j-1]!=1){                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];                }        return dp[m][n];    }};

Dungeon Game

class Solution {public:    int calculateMinimumHP(vector<vector<int>>& dungeon) {         int m = dungeon.size(), n = dungeon[0].size();         if (m==0 || n==0) {            return 0;        }       vector<vector<int> > dp(m, vector<int> (n, 0));       //初始化最后一步的血量要求       dp[m - 1][n - 1] = max(1, 1 - dungeon[m - 1][n - 1]);         //最后一列格子的初始血量        for (int i = m - 2; i >= 0; i--) {            dp[i][n - 1] = max(1, dp[i + 1][n - 1] - dungeon[i][n - 1]);        }        //最后一排格子的初始血量        for (int j = n - 2; j >= 0; j--) {            dp[m - 1][j] = max(1, 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--) {                int right = max(1, dp[i][j + 1] - dungeon[i][j]);                int down = max(1, dp[i + 1][j] - dungeon[i][j]);                dp[i][j] = min(right, down);            }        }       return dp[0][0];    }};
原创粉丝点击