寻找最小楼梯成本的动态规划问题的错误答案
Wrong answer to dynamic programming problem of finding minimum stair cost
我正在尝试解决Leetcode上的以下问题:
在楼梯上,第 i 步长分配了一些非负成本
cost[i]
(索引为 0(。支付费用后,您可以爬上一两级台阶。 您需要找到到达地板顶部的最低成本,您可以从索引为 0 的步骤或索引为 1 的步骤开始。
这是我到目前为止的解决方案。我相信我没有正确考虑我可以从楼梯 0 或楼梯 1 开始的事实,而且我不确定该怎么做。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
return helper(cost, cost.size() - 1);
}
int helper(vector<int>& cost, int currStair) {
static vector<double> minCost(cost.size(), 0);
minCost[0] = cost[0];
minCost[1] = cost[1];
if (currStair < 0 || cost.size() <= 1) {
return 0;
}
if (minCost[currStair] > 0) {
return minCost[currStair];
}
return minCost[currStair] = min(helper(cost, currStair - 1), helper(cost, currStair - 2)) + cost[currStair];
}
};
这是非常正确的想法,但我认为这是自上而下和自下而上方法的融合。
由于问题告诉我们可以从步骤 0 或 1 开始,我认为从前到后处理cost
数组更直观——您仍然可以像现在一样使用自上而下的递归 DP 方法。这样可以更轻松地区分是从第 0 步还是第 1 步开始。代码返回的最终解决方案始终是minCost[minCost.size()-1]
,它不考虑这一点。
使用static
向量会使函数非幂等,因此它将在第二次运行时保留过时的值。就 Leetcode 而言,这不会影响正确性,因为它似乎为每个测试用例创建了一个类的新实例。尽管如此,这似乎与上述普遍误解有关;初始化 0 和 1 索引并不像您想象的那样设置正确的基本情况(这就是您以自下而上的方法设置基本情况的方式(。
考虑到这一点,从第一个楼梯开始解决问题,然后走到最后一个楼梯。非静态初始化缓存向量,然后从索引 0 递归填充缓存。禁止的 2n分支因子将由缓存处理,将复杂性降低到线性,最终结果将是从阶梯 0 或 1 开始的成本的最小值。该问题将输入cost
向量限制为2 <= cost.size()
这一事实是一个很大的提示;我们知道minCost[0]
和minCost[1]
总是可以在没有先决条件的情况下进行选择。
另一个小点是,使用 0 作为空缓存标志可能会在填充为零的巨大向量上超时。由于我们需要区分未设置的索引和 0,因此我们应该使用 -1 作为标志来指示未设置的缓存索引。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
vector<int> minCost(cost.size(), -1);
helper(cost, 0, minCost);
return min(minCost[0], minCost[1]);
}
int helper(vector<int>& cost, int currStair, vector<int>& minCost) {
if (currStair >= cost.size()) return 0;
else if (minCost[currStair] >= 0) {
return minCost[currStair];
}
return minCost[currStair] = cost[currStair] +
min(helper(cost, currStair + 1, minCost),
helper(cost, currStair + 2, minCost));
}
};
- 此动态编程问题的自上而下方法
- 如何解决动态规划问题?
- 动态规划中的旅行推销员问题
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 寻找解决这个动态编程问题的提示
- 寻找最小楼梯成本的动态规划问题的错误答案
- 自上而下的动态规划与递归朴素解决方案.检查运行时执行
- 动态规划 - 原始计算器
- 如何通过动态规划方法解决这个问题?
- C++ 返回具有最小硬币的数组/向量以获得价值动态规划
- 动态规划 - 在数组中查找目标求和方式
- 转换为动态规划算法
- 我的记忆动态规划算法有什么问题?
- 使用动态规划在矩阵中的所有可能路径中具有最小总和的打印路径
- 动态规划:计算集合中存在多少个升序子集
- 潜在的动态内存问题
- 错误 C2106:'=':左操作数必须是斐波那契数列中的 l 值,方法是动态规划 C++
- 使用动态规划的值无关背包问题
- 动态规划问题
- 如何使用动态规划自顶向下的方法来解决这个问题?