文章目录
931. 下降路径最小和
题目链接:931. 下降路径最小和
算法原理
-
状态表示:
经验+题目要求:
dp[i][j]
表示到达[i,j]
位置时,最小的下降路径 -
状态转移转移方程:
根据最近的一步划分问题
-
初始化:
状态转移方程会用到左中右三个位置,所以我们可以往外扩一圈,这样就不需要担心越界的问题
这因为是最小值加上当前值,所以第一行全部设置为0不会影响元素表格第一行初始化
然后其他的设置为
+∞
即可,不会影响结果
-
**填表顺序:**从上往下
-
**返回值:**最后一行最小值
代码实现
cpp
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& matrix)
{
int n = matrix.size();
vector<vector<int>> dp(n+1, vector<int>(n+2, INT_MAX));
//初始化
for(int j = 0; j < n+2; j++) dp[0][j] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i-1][j+1])) + matrix[i-1][j-1];
}
}
int ret = INT_MAX;
for(int j = 1; j <= n; j++)
{
ret = min(ret, dp[n][j]);
}
return ret;
}
};
64. 最小路径和
题目链接:64. 最小路径和
算法原理
感觉和上一篇文章的题目一样,只不过加了个选择最小的,直接看代码吧
![](https://i-blog.csdnimg.cn/img_convert/a3e2300cf39f26726a19182396766375.png)
代码实现
cpp
class Solution {
public:
int minPathSum(vector<vector<int>>& grid)
{
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m+1, vector<int>(n+1, INT_MAX));
//初始化
dp[0][1] = dp[1][0] = 0;
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]) + grid[i-1][j-1];
}
}
return dp[m][n];
}
};
174. 地下城游戏
题目链接:174. 地下城游戏
算法原理
有点像小时候玩的按键设计的魔塔游戏。
-
**状态表示:**这里就不是以某个位置为结尾的xxx了,因为这个状态不仅受到前面的影响,还受到后面的影响。
所以用以某个位置为起点的xxx,
dp[i][j]
表示从[i, j]
位置出发,到达终点所需的最低初始健康点数 -
状态转移方程:
假设以
[i,j]
位置为起点,走到终点,它可以往下或者往右走
假设此时
dp[i][j]
为x
,要走到下一步,最起码要大于或等于下个位置的最低血量然后两种情况取较小的即可
Tips:
此时
[i, j]
位置可能是一个加血包,如果太大,就会是负数了,这样就符合逻辑,所以还需要比较一下
代码实现
cpp
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, INT_MAX));
dp[m][n-1] = dp[m-1][n] = 1;
for(int i = m-1; i >= 0; i--)
{
for(int j = n-1; j >= 0; j--)
{
dp[i][j] = min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j];
dp[i][j] = max(1, dp[i][j]);
}
}
return dp[0][0];
}
};