[Leetcode]Dynamic Programming

Dynamic Programming

174. Dungeon Game

Dungeon Game

At first, I wanna use DFS to search all of the possible states, but I finally find that it will take too much time. It is likely that there are some methods to optimize to avoid TLE, but I can’t find that. However, the better solution isn’t DFS but dynamic programming. As usual, we have to define the state and state transformation functions. So, what is the state? If we start from the beginning point, we have to take care of MinHP and CurHP. It will be hard for us to define state transformation function. On the contrary, if we start from the endpoint, it will be easy. We just need to define a state dp[i][j] as the necessary MinHP at [i, j] is is dp[i][j] so that it can reach the endpoint safely. Since that, the state transformation function is easy:

dp[i][j] = min(dp[i][j + 1], dp[i + 1][j) - dungeon[i][j] <= 0 
            ? 1 : min(dp[i][j + 1], dp[i + 1][j) - dungeon[i][j]

Code

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int M = dungeon.size();
        int N = dungeon[0].size();
        vector<vector<int>> dp(M + 1, vector<int>(N + 1, 100000000));
        dp[M][N - 1] = 1;
        dp[M - 1][N] = 1;
        for (int i = M - 1; i >= 0; i--) {
            for (int j = N - 1; j >= 0; j--) {
                int need = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j];
                dp[i][j] = need <= 0 ? 1 : need;
            }
        }
        return dp[0][0];
    }
};

[TLE]

struct Node {
    int M;
    int N;
    int MinHP;
    int CurMP;
    Node() {
        M = 0;
        N = 0;
        MinHP = 1;
        CurMP = 1;
    }
};

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int M = dungeon.size();
        int N = dungeon[0].size();
        int minHP = 1000000000;
        vector<vector<int>> MinHP_records = vector<vector<int>>(M, vector<int>(N, 100000000));
        vector<vector<int>> CurHP_records = vector<vector<int>>(M, vector<int>(N, 100000000));
        Node knight;
        queue<Node> states;
        states.push(knight);
        while (!states.empty()) {
            knight = states.front();
            states.pop();
            if (dungeon[knight.M][knight.N] < 0) {
                if (knight.CurMP <= -dungeon[knight.M][knight.N]) {
                    knight.MinHP += -dungeon[knight.M][knight.N] - knight.CurMP + 1;
                    knight.CurMP = 1;
                } else {
                    knight.CurMP += dungeon[knight.M][knight.N];
                }
            } else {
                knight.CurMP += dungeon[knight.M][knight.N];
            }
            if (MinHP_records[knight.M][knight.N] > knight.MinHP || CurHP_records[knight.M][knight.N] < knight.CurMP) {
                MinHP_records[knight.M][knight.N] = min(MinHP_records[knight.M][knight.N], knight.MinHP);
                CurHP_records[knight.M][knight.N] = max(CurHP_records[knight.M][knight.N], knight.CurMP);
                if (knight.M == M - 1 && knight.N == N - 1) {
                    if (minHP > knight.MinHP) {
                        minHP = knight.MinHP;
                    }
                } else {
                    if (knight.M != M - 1) {
                        Node downNode;
                        downNode.M = knight.M + 1;
                        downNode.N = knight.N;
                        downNode.MinHP = knight.MinHP;
                        downNode.CurMP = knight.CurMP;
                        states.push(downNode);
                    }
                    if (knight.N != N - 1) {
                        Node rightNode;
                        rightNode.M = knight.M;
                        rightNode.N = knight.N + 1;
                        rightNode.MinHP = knight.MinHP;
                        rightNode.CurMP = knight.CurMP;
                        states.push(rightNode);
                    }
                }
            }
        }
        return minHP;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值