Wrong answer to dynamic programming problem of finding minimum stair cost

Deadly 提交于 2020-01-05 04:09:15

问题


I am trying to solve the following problem on Leetcode:

On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed).

Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1.

This is my solution so far. I believe I'm not correctly taking into account the fact that I can start at stair 0, or stair 1, and I'm not sure how to do so.

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];

    }
};

回答1:


This is very much the right idea, but I think it's sort of a conflation of top-down and bottom-up approaches.

Since the problem tells us we can start on steps 0 or 1, I think it's more intuitive to work through the cost array from front to back--you can still use a top-down recursive DP approach as you're doing. This makes it easier to distinguish between starting at the 0th or 1st step. The final solution that's returned by your code is always minCost[minCost.size()-1] which doesn't take this into account.

Using a static vector makes the function non-idempotent, so it'll persist stale values on a second run. This doesn't impact correctness as far as Leetcode is concerned because it seems to create a new instance of your class per test case. Nonetheless, it seems related to the above general misunderstanding; initializing 0 and 1 indices isn't setting a correct base case as you may think (this is how you'd set the base case in a bottom-up approach).

With this in mind, approach the problem from the first stair and walk forward to the last. Initialize the cache vector non-statically, then populate the cache recursively from index 0. The prohibitive 2n branching factor will be handled by the cache, reducing the complexity to linear, and the final results will be the min of the cost of starting at stair 0 or 1. The fact that the problem constrains the input cost vector to 2 <= cost.size() is a big hint; we know minCost[0] and minCost[1] will always be available to choose between without preconditions.

Another minor point is that using 0 as the empty cache flag could time out on huge vectors filled with zeroes. Since we need to distinguish between an unset index and a 0, we should use -1 as the flag to indicate an unset cache index.

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));
    }
};


来源:https://stackoverflow.com/questions/59230399/wrong-answer-to-dynamic-programming-problem-of-finding-minimum-stair-cost

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!