C++ 求楼梯费用最小的动态规划问题的错误答案

C++ 求楼梯费用最小的动态规划问题的错误答案,c++,algorithm,recursion,dynamic-programming,C++,Algorithm,Recursion,Dynamic Programming,我正在尝试解决Leetcode上的以下问题: 在楼梯上,第i步分配了一些非负成本cost[i](0索引) 一旦你付了费用,你可以爬上一两步。 您需要找到到达楼层顶部的最低成本,您可以从索引为0的步骤开始,也可以从索引为1的步骤开始 到目前为止,这是我的解决方案。我认为我没有正确地考虑到我可以从楼梯0或楼梯1开始这一事实,我不知道如何这样做 class Solution { public: int minCostClimbingStairs(vector<int>& c

我正在尝试解决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];

    }
};
类解决方案{
公众:
int最小成本攀爬台(向量和成本){
返回帮助程序(cost,cost.size()-1);
}
int辅助对象(向量和成本,int currStair){
静态向量minCost(cost.size(),0);
最小成本[0]=成本[0];
最小成本[1]=成本[1];
如果(currStair<0 | | cost.size()0){
返回最小成本[当前价格];
}
return minCost[currStair]=min(helper(cost,currStair-1),helper(cost,currStair-2))+cost[currStair];
}
};

这是一个非常正确的想法,但我认为这是一种自上而下和自下而上方法的结合

因为问题告诉我们可以从第0步或第1步开始,所以我认为从前面到后面处理
成本
数组更直观——您仍然可以使用自顶向下的递归DP方法。这样就更容易区分从第0步开始还是从第1步开始。代码返回的最终解决方案始终是
minCost[minCost.size()-1]
,它没有考虑到这一点

使用
静态
向量会使函数变为非-,因此它会在第二次运行时保留过时的值。就Leetcode而言,这不会影响正确性,因为它似乎会为每个测试用例创建一个新的类实例。尽管如此,这似乎与上述普遍误解有关;初始化0和1索引并不像您所想的那样设置正确的基本情况(这是您在自底向上方法中设置基本情况的方式)

记住这一点,从第一级开始解决问题,然后向前走到最后一级。非静态初始化缓存向量,然后从索引0递归填充缓存。禁止的2n分支因子将由缓存处理,将复杂性降低为线性,最终结果将是从0级或1级开始的最小成本。问题将输入
cost
向量约束为
2=cost.size())的事实返回0;
如果(最小成本[currStair]>=0),则为else{
返回最小成本[当前价格];
}
返回最小成本[currStair]=成本[currStair]+
最小值(助手(成本,当前楼梯+1,最小成本),
助手(成本,currStair+2,minCost));
}
};

这是一个非常正确的想法,但我认为这是一种自上而下和自下而上方法的结合

因为问题告诉我们可以从第0步或第1步开始,所以我认为从前面到后面处理
成本
数组更直观——您仍然可以使用自顶向下的递归DP方法。这样就更容易区分从第0步开始还是从第1步开始。代码返回的最终解决方案始终是
minCost[minCost.size()-1]
,它没有考虑到这一点

使用
静态
向量会使函数变为非-,因此它会在第二次运行时保留过时的值。就Leetcode而言,这不会影响正确性,因为它似乎会为每个测试用例创建一个新的类实例。尽管如此,这似乎与上述普遍误解有关;初始化0和1索引并不像您所想的那样设置正确的基本情况(这是您在自底向上方法中设置基本情况的方式)

记住这一点,从第一级开始解决问题,然后向前走到最后一级。非静态初始化缓存向量,然后从索引0递归填充缓存。禁止的2n分支因子将由缓存处理,将复杂性降低为线性,最终结果将是从0级或1级开始的最小成本。问题将输入
cost
向量约束为
2=cost.size())的事实返回0;
如果(最小成本[currStair]>=0),则为else{
返回最小成本[当前价格];
}
返回最小成本[currStair]=成本[currStair]+
最小值(助手(成本,当前楼梯+1,最小成本),
助手(成本,currStair+2,minCost));
}
};
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));
    }
};