CC31 三角形
给出一个三角形,计算从三角形顶部到底部的最小路径和,每一步都可以移动到下面一行相邻的数字,例如,给出的三角形如下:
[[20],[30,40],[60,50,70],[40,10,80,30]]
最小的从顶部到底部的路径和是20 + 30 + 50 + 10 = 110。
注意:
如果你能只用O(N)的额外的空间来完成这项工作的话,就可以得到附加分,其中N是三角形中的行总数。
试题链接CC31 三角形
解题思路,动态规划,下面分为两种思想
- 状态定义 F[i][j] 从最顶层到当前位置最短路径和
- 状态方程 F[i][j] = min(F[i-1][j], F[i-1][j-1]) + arr[i][j]
- 初始化 F[0][0] = arr[0][0]
注意,对与我们当前点只能通过两种方式到达,因此我们需要判断我们上面一层的左侧是否存在元素,这点很重要
还要考虑一个问题,我们的状态定义的是从最上层到当前位置的最小路径和,也就是我们到达最后一层会出现很多个和,我们要看他们的最小值.
class Solution
{
public:
/// @brief 自上向下 这道题连题目都没有说清楚,线下的时候只能 垂直和右下
/// @param triangle
/// @return
int minimumTotal(vector<vector<int>> &triangle)
{
if (triangle.empty())
return -2;
vector<vector<int>> dp(triangle.size());
for (int i = 0; i < triangle.size(); ++i)
{
vector<int> v(i + 1, -1);
dp[i] = v;
}
dp[0][0] = triangle[0][0];
for (int i = 1; i < triangle.size(); i++)
{
for (int j = 0; j < triangle[i].size(); j++)
{
if (j != 0 && i == j)
{
dp[i][j] = triangle[i][j] + dp[i - 1][j - 1];
continue;
}
int minNum = dp[i - 1][j];
if (j - 1 >= 0)
{
minNum = min(minNum, dp[i - 1][j - 1]);
}
dp[i][j] = minNum + triangle[i][j];
}
}
// 找最小值
int result = dp[triangle.size() - 1][0];
for (int i = 1; i < dp[triangle.size() - 1].size(); ++i)
{
if (result > dp[triangle.size() - 1][i])
result = dp[triangle.size() - 1][i];
}
return result;
}
};
现在来是从下往上,这里我们也是动态规划
- 状态定义 F[i][j] : 表示从最底层到当前位置的最短路径和
- 状态方程 F[i][j] = min(F[i+1][j], F[i+1][j+1]) + arr[i][j]
- 初始化 最后一行都要初始化
这里要注意我们当前位置从下层只能从下层和下层的右边一个拿到,我们要的结果就是F[0][0]
class Solution {
public:
int minimumTotal(vector<vector<int> >& triangle) {
if (triangle.empty())
return -1;
std::vector<std::vector<int>> dp(triangle.size());
for (int i = 0; i < triangle.size(); i++)
{
std::vector<int> v(i + 1, -1);
dp[i] = v;
}
// 初始化
for (int i = 0; i < triangle.back().size(); i++)
{
dp[triangle.size() - 1][i] = triangle[triangle.size() - 1][i];
}
// 开始动归
for (int i = (int)triangle.size() - 1 - 1; i >= 0; i--)
{
for (int j = 0; j < triangle[i].size(); j++)
{
dp[i][j] = std::min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j];
}
}
return dp[0][0];
}
};