Dungeon Game (GRAPH - DP)

QUESTION

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)

1st TRY

class Solution {
public:
    int calculateMinimumHP(vector<vector<int> > &dungeon) {
        minInitHP = INT_MAX;
        dfs(dungeon,0,0,0,0);
        return minInitHP+1;
    }
    void dfs(vector<vector<int> > &dungeon, int m, int n, int currentHP, int currentMinInitHP)
    {
        currentHP -= dungeon[m][n];
        currentMinInitHP= max(currentMinInitHP,currentHP);
        if(currentMinInitHP>minInitHP) return;
        if(m==dungeon.size()-1 && n==dungeon[0].size()-1)
        {
            currentHP = min(currentHP,currentMinInitHP);
            return;
        }
        if(m!=dungeon.size()-1) dfs(dungeon,m+1,n,currentHP,currentMinInitHP);
        if(n!=dungeon[0].size()-1) dfs(dungeon,m,n+1,currentHP,currentMinInitHP);

    }
private:
    int minInitHP;
};

Result: Time Limit Exceeded

2nd TRY

用空间换时间,动态规划

class Solution {
public:
    int calculateMinimumHP(vector<vector<int> > &dungeon) {
        int m = dungeon.size();
        int n = dungeon[0].size();  

        int **dp = new int*[m]; // min HP needed when knight come here
        for(int i=0; i < m; i++)
            dp[i] = new int[n];

        dp[0][0] = 0 - dungeon[0][0];for(int i = 1; i < m; i++)
        {
            dp[i][0] = max(dp[i-1][0]-dungeon[i][0], dp[i-1][0]);
        }
        for(int i = 1; i < n; i++)
        {
            dp[0][i] = max(dp[0][i-1]-dungeon[0][i], dp[0][i-1]);
        }
        for(int i = 1; i < m; i++)
        {
            for(int j = 1; j < n; j++)
            {
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])-min(0,dungeon[i][j]);
            }
        }
        return max(1,dp[m-1][n-1]+1);
    }
};

Result: Wrong Answer

Input: [[0,5],[-2,-3]]
Output: 4
Expected: 1

3rd TRY

状态的保存有问题,需要保存两个状态:到当前格在初始时需要的HP,以及到了当前格的HP

所以要从下往上填状态,那么只要保存一个状态,当前格的HP

class Solution {
public:
    int calculateMinimumHP(vector<vector<int> > &dungeon) {
        int m = dungeon.size();
        int n = dungeon[0].size();  

        int **dp = new int*[m]; // min HP needed when knight from here to end
        for(int i=0; i < m; i++)
            dp[i] = new int[n];

        dp[m-1][n-1] = max(0 - dungeon[m-1][n-1],0);
        for(int i = m-2; i >= 0; i--)
        {
            dp[i][n-1] = max(dp[i+1][n-1]-dungeon[i][n-1],0);
        }
        for(int i = n-2; i >= 0; i--)
        {
            dp[m-1][i] = max(dp[m-1][i+1]-dungeon[m-1][i],0);
        }
        for(int i = m-2; i >= 0; i--)
        {
            for(int j = n-2; j >= 0; j--)
            {
                dp[i][j]=max(min(dp[i+1][j],dp[i][j+1])-dungeon[i][j],0);
            }
        }
        return dp[0][0]+1;
    }
};

Result: Accepted

时间: 2024-10-12 13:09:48

Dungeon Game (GRAPH - DP)的相关文章

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

codeforces340D - Bubble Sort Graph dp + 最长上升子序列

题意:给你长为n的序列 ,每个节点都和在它前面且值比他大的点产生一条边,问你一个最大 两两点没有边的集合的 集合元素有多少 解题思路:想了半天才发现是最长上升子序列.. 解题代码: 1 // File Name: 340d.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月03日 星期日 12时31分24秒 4 5 #include<vector> 6 #include<list> 7 #include<map>

64. Minimum Path Sum (Graph; DP)

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. class Solution { public: int minP

63. Unique Paths II (Graph; DP)

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 middl

62. Unique Paths (Graph; DP)

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in t

codeforces 459E E. Pashmak and Graph(dp)

题目链接: codeforces 459E 题目大意: 给出n个点,m条边的有向图,每个边有边权,求一条最长的边权上升的路径的长度. 题目分析: 定义dp[i]表示第i条边结尾的情况下的最长路径. 定义g[i]表示点i结尾的情况的最长路径. 对所有的边进行排序,那么前面的边只可能小于等于后面的边. 所以dp[i] = g[e[i].u]+1 然后只需要特殊考虑一下边相等的情况,更新g[i]即可,具体见代码. AC代码: #include <iostream> #include <cstr

codeforces 340D D. Bubble Sort Graph(dp+线段树)

题目链接: codeforces 340D 题目大意: 给出一个程序,就是冒泡排序,每次如果发现相邻两个数前一个大于后一个,交换位置后建边,问最后得到的这个图中的最大独立集,这个最大独立集定义为所有的点都不相邻的最大点的集合的规模. 题目分析: 首先我们可以知道对于a[i],它只会且一定会与后面的比它小的建边,所以我们只需要固定第一个点,然后找最长上升子序列即可.(这样能够保证没有相邻的点) 定义状态dp[i]为以i项结尾的最长上升子序列的长度. 转移方程如下: dp[i]=max{dp[j]+

LeetCode 174. Dungeon Game(DP)

题目 题意:每个格子里都有数字,负数代表你会少血,正数代表你会加血,当你的血量为0的时候就死了,从左上角出发,到右下角,问你一开始最少的血量是多少.整个过程中不能有血量为0的情况. 题解:只能走下或者走右.这种有向无环图,八成都是动态规划.但是如果从左上角开始规划,有很多情况要考虑.从右下角开始规划,才可以. dp[i][j]代表从i,j到右下角,最低需要多少血量. class Solution { public: int dp[1005][1005]; int calculateMinimum

【leetcode】Dungeon Game

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