第十三周(Dungeon Game)

第十三周(Dungeon Game)

目录:

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

一、本周完成题目

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

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

#TitleDifficulty
63Unique Paths IIMedium
174 Dungeon GameHard

题目内容

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];

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值