lc 174. Dungeon Game

https://leetcode.com/problems/dungeon-game/

一个二维矩阵n*m做的地图上,每个都有或正或负的整数,对一从左上到右下的最短路径(每步只能向右或者下)我们走的同时会记录当前位置的累加和s,所以一条路会有n+m-2个位置,所有这些和的最小值是该路径的价值,求价值最大的路。

一个奇怪的dp,这是首先想到的。

因为这个题目让我费解了好一段时间,所以记录思考过程比记录最终解法更有意义。

dp会有一个对于最好状态的记录,这个最好状态记录了之后,其怎么取得的不重要,只有这个值重要,以供后续点使用。(这是一种马尔可夫链的情况,后续状态仅仅由当前决定,却与历史历史无关),由此化指数级别为多项式级别。

但是观察发现这个题目却有两个因素的抗衡,一个是最小值,一个是当前值。有点情况(后面遇到大负数)会希望这个当前值最大化,另一些情况(后面遇到大正数)会希望这个最小值最大化。而继续观察发现,最优解也不必然出现在两个因素的某个最值里,可能某种平衡一点的取值是最优的。dp里面这种情况就要用升维了。对于某个最小值,能取得最大当前值是多少,或者反之。然后本题可以用再次基础上加个优化,就是a的两个因素都差于b,那么a直接被pop出去,可以进一步减少计算量。但是仍然有指数级别的因素参与。

怎么办?强大的二分。。。庞大的数据量在log面前是多么的不堪一击!

二分答案。化优化问题为判断问题。以后我决定了,每次打比赛之前把二分这两个字贴在桌子上。

class Solution:
    def calculateMinimumHP(self, dungeon):
        """
        :type dungeon: List[List[int]]
        :rtype: int
        """
        h=len(dungeon)
        w=len(dungeon[0])
        def check(hl):
            mp=[[None]*w for i in range(h)]
            mp[0][0]=dungeon[0][0]+hl
            if mp[0][0]<=0:
                return False
            for i in range(1,w):
                mp[0][i]=None if mp[0][i-1]==None else mp[0][i-1]+dungeon[0][i]
                if mp[0][i]==None or mp[0][i]<=0:
                    mp[0][i]=None
            for i in range(1,h):
                mp[i][0]=None if mp[i-1][0]==None else mp[i-1][0]+dungeon[i][0]
                if mp[i][0]==None or mp[i][0]<=0:
                    mp[i][0]=None
            for i in range(1,h):
                for j in range(1,w):
                    u=mp[i-1][j]
                    l=mp[i][j-1]
                    c=dungeon[i][j]
                    if u==None and l==None:
                        mp[i][j]=None
                    elif u==None:
                        mp[i][j]=l+c if l+c>0 else None
                    elif l==None:
                        mp[i][j] = u + c if u + c > 0 else None
                    else:
                        mp[i][j] = max(l,u)+c
                        if mp[i][j]<=0:
                            mp[i][j]=None
            if mp[-1][-1]!=None:
                return True
            return False
        upper=10
        for i in range(h):
            for j in range(w):
                if dungeon[i][j]<0:
                    upper-=dungeon[i][j]
        if check(1):
            return 1
        l,r=1,upper
        while r-l>1:
            m=(r+l)//2
            if check(m):
                r=m
            else:
                l=m
        return r

原文地址:https://www.cnblogs.com/waldenlake/p/10689426.html

时间: 2024-10-28 11:04:38

lc 174. Dungeon Game的相关文章

leetcode[174]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 wa

Java for LeetCode 174 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 wa

174. 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 wa

leetcode 174. Dungeon Game 地牢游戏 --------- java

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 wa

[email&#160;protected] [174] Dungeon Game (Dynamic Programming)

https://leetcode.com/problems/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 positione

[leedcode 174] 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 wa

174 Dungeon Game 地下城游戏

一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格布局.我们英勇的骑士(K)最初被安置在左上角的房间里,并且必须通过地下城对抗来拯救公主.骑士具有以正整数表示的初始健康点.如果他的健康点在任何时候降至 0 或以下,他会立即死亡.有些房间由恶魔守卫,因此骑士在进入这些房间时失去健康点(负整数):其他房间要么是空的(0),要么包含增加骑士身体健康的魔法球(正整数).为了尽快到达公主,骑士决定只会每次向右或向下移动一步.写一个函数来确定骑士的最低初始健康点

[动态规划] leetcode 174 Dungeon Game

problem:https://leetcode.com/problems/dungeon-game 看了这道题的tag我用了二分 + 简化dp(只需求特定血量能否达到)来做,能过但是速度好慢.一看评论区发现大家都是用纯dp过的,我哭了. class Solution { public: int m, n; bool canSave(vector<vector<int>>& dungeon, int life) { vector<vector<int>&g

蠡口174. Dungeon Game

一开始想的是设所求数为x,那么遍历所有可能路径,看最小血量花销. 后来想想对矩阵一顿操作后,返回一个值,而非所有路径的具体值,很有可能是DP.于是往DP的方向想,我们能确定的是救到公主后,骑士的血量至少为1,然后求起始位置是骑士的最低血量可以是多少.这样一想,自然是从右下往左上递推. 1.我们建立dp二维数组:dp[i][j]表示进入房间(i,j)之前骑士血量可以最低是多少. 2.初始边界: 2.1)我们先来想想进入最后的房间之前骑士血量可以最低是多少?最后一个房间可以是: 1)怪兽(即dung