算法課作業系列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),這樣,我們的算法就設計出來啦!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章