174. Dungeon Game

一道动态规划。这道题的难点在于要保证整个过程的血量都要≥1(即使后来的血加回来了大于0也不行,走到一半就死了),又需要是最小的血量,包括初始房间和最后一个房间。

1.到达最后一个房间时要被-5,所以到达时的最小值应该是6,即1-d[2][2],但是如果这个房间是加血的(≥0),会算出一个负数来是不对的,因为从上个房间来的话最小值至少是1。
2.对于下边界和右边界,只能朝一个方向走,所以先处理。现在已知d[2][2]=6,那么d[1][2]还可以加一点血,那么到d[1][2]=d[2,2]-d[1,2],同理有一个最小底线1。
3.对于剩下的数字,有两个方向可以选择,那么肯定是选择需要的血少的那个方向,比如算d[1][1]可以选择向d[1][2]或d[2][1]走,d[1][2]需要6点血,d[2][1]只需要1点血,那d[1][1]=d[2][1]-d[1][1]=11。别忘了还有小于0的情况全都算作1。

所以得出状态转移方程dungeon[i][j] = max(min(dungeon[i][j + 1], dungeon[i + 1][j]) - dungeon[i][j], 1)

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>> &dungeon) {
        int m=dungeon.size();
        int n=dungeon[0].size();
        dungeon[m-1][n-1]=max(1-dungeon[m-1][n-1],1);
        
        for (int i=m-2;i>=0;i--)
           dungeon[i][n-1]=max(-dungeon[i][n-1]+dungeon[i+1][n-1],1);
        for (int i=n-2;i>=0;i--)
           dungeon[m-1][i]=max(-dungeon[m-1][i]+dungeon[m-1][i+1],1);
        for (int i=m-2;i>=0;i--)
           for(int j=n-2;j>=0;j--)
               dungeon[i][j]=max(min(dungeon[i+1][j],dungeon[i][j+1])-dungeon[i][j],1);
        return dungeon[0][0];
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值