動態規划(股票交易)---只能進行兩次的股票交易


只能進行兩次的股票交易

123. Best Time to Buy and Sell Stock III (Hard)

題目描述:

  一共只能進行兩次股票交易,求能夠取得的最大利潤。

思路分析:

  這道題是Best Time to Buy and Sell Stock的擴展,現在我們最多可以進行兩次交易。我們仍然使用動態規划來完成,事實上可以解決非常通用的情況,也就是最多進行k次交易的情況。
  這里我們先解釋最多可以進行k次交易的算法,然后最多進行兩次我們只需要把k取成2即可。我們還是使用“局部最優和全局最優解法”。我們維護兩種量,一個是當前到達第i天可以最多進行j次交易,最好的利潤是多少(global [i] [j]),另一個是當前到達第i天,最多可進行j次交易,並且最后一次交易在當天賣出的最好的利潤是多少(local [i] [j])。下面我們來看遞推式,全局的比較簡單,
  global [i] [j]=max(local [i] [j],global [i-1] [j]),
  也就是取當前局部最好的,和過往全局最好的中大的那個(因為最后一次交易如果包含當前天一定在局部最好的里面,否則一定在過往全局最優的里面)。對於局部變量的維護,遞推式是
local [i] [j]=max(global [i-1] [j-1]+max(diff,0),local [i-1] [j]+diff),

  也就是看兩個量,第一個是全局到i-1天進行j-1次交易,然后加上今天的交易,如果今天是賺錢的話(也就是前面只要j-1次交易,最后一次交易取當前天),第二個量則是取local第i-1天j次交易,然后加上今天的差值(這里因為local [i-1] [j]比如包含第i-1天賣出的交易,所以現在變成第i天賣出,並不會增加交易次數,而且這里無論diff是不是大於0都一定要加上,因為否則就不滿足local [i] [j]必須在最后一天賣出的條件了)。

代碼:

public int maxProfit(int []prices,int k){
    if(prices==null||prices.length==0)
        return 0;
    int []local=new int [3];
    int []global=new int [3];
    for(int i=0;i<prices.length-1;i++){
        int diff=prices[i+1]-prices[i];
        for(int j=2;j>=1;j--){
            local[j]=Math.max(global[j-1]+(diff>0?diff:0),local[j]+diff);
            global[j]=Math.max(local[j],global[j]);
        }
    }
    return global[2];
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM