简单动态规划-爬楼梯的最小代价
这里直接给个leetcode的链接吧,本人太懒了不想写题干。
题目
所谓的到楼梯顶就是要越过这个数组。比如数组长度为n,那么就要抵达n这个位置。一开始我觉得很难,不知道怎么做,因为它说可以从0开始,也可以从1开始,那我怎么知道从0开始还是从1开始?而且,你到某个地方后,还得根据那个值判断是跳两格还是只跳一格,这就很狗了。而且而且,貌似这道题跟以前的题不一样啊,以前的动态规划题都不会越过数组的,你这要我怎么从数组最后一个元素开始分析?
后来一看题解,哈哈只能说我题目做得太少了。
先来说说动态规划的解法:
根本不需要考虑那么多乱七八糟的事情,dp数组开到cost数组长度+1就行了。然后,对于某一个位置i,我们随便分析一下就能知道,能跳到这个位置,那无非只有两种情况,一是从i-1这个位置跳过来,二是从i-2这个位置跳过来。然后,因为题目要求的最小代价之和,那我肯定要记录之前已经花费的所有代价,因此,动态规划方程就是:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]).
1 public int calMinCost(int[] cost) { 2 int n = cost.length; 3 int[] dp = new int[n+1]; 4 dp[0] = 0; 5 dp[1] = 0; 6 for (int i = 2; i <= n; ++i) { 7 dp[i] = Math.min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]); 8 } 9 return dp[n]; 10 }
但是这样做的空间复杂度为O(n),我们可以优化一下:
可以看到其实最终的代价之和只与cost数组有关,那我们完全可以用两个变量来模拟dp数组,只需要有限的额外空间。
1 public int calMinCost(int[] cost) { 2 int n = cost.length; 3 int pre = 0; 4 int cur = 0; 5 for (int i = 2; i <= n; ++i) { 6 int next = Math.min(cur + cost[i-1], pre + cost[i-2]); 7 pre = cur; 8 cur = next; 9 } 10 return cur; 11 }
这样就行了。