算法课作业系列7——Best Time to Buy and Sell Stock with Transaction Fee

算法课作业系列(7)

Best Time to Buy and Sell Stock with Transaction Fee

题目描述

Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.

You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)

Return the maximum profit you can make.

Example 1:
Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
Buying at prices[0] = 1
Selling at prices[3] = 8
Buying at prices[4] = 4
Selling at prices[5] = 9
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

Note:

0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

思路

其实这道题不算难,主要考的是动态规划的问题,受到揹包问题的影响,我自己想到一个算法,时间复杂度为O(n^2),而提交之后给出了超时的判定,在查看讨论区后,自己又根据别人的思想,写好了第二个算法。
值得一提的是,动态规划的算法大多数都比较短小,而思想也是把原问题分解之后求解,和分治类似。在想到动态规划的算法之前可能题目会很复杂,但是一旦找到了状态转移式之后,一切也就迎刃而解了,那么接下来就来看看这两个思路。

  1. 从后往前
    其实这个想法个人认为是很自然而然的,要求最大利益,无非就是当天两种可能,卖或者不卖,先把公式表示出来:
    C(i) = max{p(j) - p(i) - fee + C(j), C(i + 1)} j->(i + 1, n)
    下面来详细说说这个式子,C代表最大利润,p为价格,那么第i天的最大利润就是 第j天卖出加上第j天开始的最大利润i+1天的利润 的最大值。怎么去理解呢?假设我第i天是持有货物的,那么我的利润就是第j天卖出得到的利润,而第j天又可以买入新的货物,因此要加上第j天的最大利润;而如果我第i天手上没有货物,则我第i天的利润也就是第i+1天的利润,具体是第i天买入之后卖出还是第j天什么都不做,就要看这两种结果谁更大就好。我们的前面的值是依赖后面的,因此我们要从最后一天开始往前看,最后一天一定是什么都不做,利润为0,继续往前,只要分解成小问题就可以了,具体的参考上面的公式。
  2. 从前往后
    上面那个是我个人的思考,这里介绍一下另外一个思路,同样的先给出公式
    HOLD(i) = max{HOLD(i - 1), SOLD(i - 1) - p(i)}
    SOLD(i) = max{SOLD(i - 1), HOLD(i - 1) + p(i) - fee}
    上面的HOLD代表第i天持有货物的利润,而SOLD代表第i天没有货物的利润,因此我们可以知道:
    HOLD(i)一种情况下是前一天没有货物,但是当天买了货物;另一种情况是前一天有货物,当天什么都没做,具体看上面的公式
    SOLD(i)一种情况是前一天就没有,当天什么都没做;另一种是前一天有,今天卖出了,可以参考上面公式
    而第一天的话,考虑到没有本金,那么SOLD(0)就应该为0,HOLD(0)就应该为-p(0),这样,我们的算法就设计出来啦!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章