Leetcode 每日一题 地下城游戏 动态规划(golang)

题目
在这里插入图片描述
分析过程
1.这道题还是要用到动态规划,但是与之前的有些不同,如果从最大收益正向考虑时,会产生三个储存时间,而且不是简单的在最后加一个判断条件,勇士在中间也必须保持正血量,因此行不通,就算实现了,时间复杂度也过高。
2.采用倒推的方法,根据题意要救出公主,从公主的位置出发,若公主当前位置为正,则勇士健康值最少为1,若为负,则需要上一步dp-当前格数值
3.用dp[i][j] 表示从坐标 (i,j) 到终点所需的最小初始值,在一般情况下,我们只需要关注向右和向上这两者健康点最小值

给出动态规划方程

dp[i][j]=max(min(dp[i+1][j],dp[i][j+1])−dungeon(i,j),1)

代码

func calculateMinimumHP(dungeon [][]int) int {

	n := len(dungeon)
	m := len(dungeon[0])    //读取网格数
	dp := make([][]int, n)  //创建动态存储空间,即勇士健康点
	for i := 0; i < n; i++ {
		dp[i] = make([]int, m)
	}
	if dungeon[n-1][m-1] > 0 {
	dp[n-1][m-1] = 1//判断最后一格即公主所在格数的上面和左边两格数值是否大于0,若是则勇士健康点为1
	} else {
		dp[n-1][m-1] = 1 - dungeon[n-1][m-1] //不是,则上一步dp-当前格数值
	}
	for i := n - 1; i >= 0; i-- {
		for j := m - 1; j >= 0; j-- {
			if i == n-1 && j == m-1 {
				continue      //判断健康点是否大于0,不是则死亡
			} else if j == m-1 {
				dp[i][j]=Max(1,(dp[i+1][j]-dungeon[i][j]))
			} else if i == n-1 {
				dp[i][j]=Max(1, (dp[i][j+1]-dungeon[i][j]))
			}else {
                t1 :=Max(1,dp[i+1][j]-dungeon[i][j])
                t2 :=Max(1,dp[i][j+1]-dungeon[i][j])
				dp[i][j]=Min(t1,t2)
			}                    //两次循环判断一般情况,获得最小值
		}
	}                         
	return dp[0][0]
}
func Min(x, y int) int {
    if x < y {
        return x
    }
    return y
}

func Max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

猜你喜欢

转载自blog.csdn.net/qq_46595591/article/details/107298114