動態規劃_買賣股票的最佳時機|||_1
阿新 • • 發佈:2019-02-05
題目要求是“最多可以完成兩筆交易”。則一共有三種情況:不交易;完成一次交易;完成兩次交易。其中,不交易的最大收益是0,完成一次交易包含當天買入當天賣出的情況,所以“完成一次交易”的方案已經包含了“不交易”,故總共有兩種交易方案:完成一次交易和完成兩次交易。用符號(i, j)表示在第i天到第j天的閉區間內完成一次交易所能獲得的最大收益,其中1<=i<=N-1,i<=j<=N-1。這裡的“完成·一次交易”包含以下幾種情況:
2.1 在第k天買入,且在第k天賣出;i<=k<=j,收益為0
2.2 在第p天買入,且在第q天賣出,i<=p<q<=j ,此時i<j,收益為prices[q]-prices[p];
則原問題的解是:max{(1,1)+(1,N), (1,2)+(2,N),..., (1,N)+(N,N)}。此時可以參考 動態規劃_最大子陣列||_1
建立陣列dp_i[N],陣列元素dp_i[i]是 只進行一次交易,且在第i天賣出股票時的最大收益,則dp_i[1]=0;
dp_i[i]=max{dp_i[i-1]+prices[i]-prices[i-1],0}.
建立陣列dpi[N],陣列元素dpi[i]=(1, i)。則dpi[1]=0;
dpi[i]=max{dpi[i-1],dp_i[i]}.
建立陣列dp_N[N],陣列元素dp_N[i]是 只進行一次交易,且在第i天買入時的最大收益,,則dp_N[N]=0;
dp_N[i]=max{dp_N[i+1]+prices[i+1]-prices[i],0}.
建立陣列dpN[N],陣列元素dpN[i]=(i, N)。則dpN[N]=0;
dpN[i]=max{dpN[i+1],dp_N[i]}.
3.【程式碼】
class Solution { public: /** * @param prices: Given an integer array * @return: Maximum profit */ int maxProfit(vector<int> &prices) { // write your code here int N=prices.size(); if(N<2) { return 0; } vector<int> dp_i(N,0); for(int i=1;i<N;++i) { dp_i[i]=dp_i[i-1]+prices[i]-prices[i-1]; dp_i[i]=dp_i[i]>0?dp_i[i]:0; } vector<int> dpi(N,0); for(int i=1;i<N;++i) { dpi[i]=dpi[i-1]>=dp_i[i]?dpi[i-1]:dp_i[i]; } vector<int> dp_N(N,0); for(int i=N-2;i>=0;--i) { dp_N[i]=dp_N[i+1]+prices[i+1]-prices[i]; dp_N[i]=dp_N[i]>=0?dp_N[i]:0; } vector<int> dpN(N,0); for(int i=N-2;i>=0;--i) { dpN[i]=dpN[i+1]>=dp_N[i]?dpN[i+1]:dp_N[i]; } int res=0; for(int i=0;i<N;++i) { res=res>=(dpi[i]+dpN[i])?res:(dpi[i]+dpN[i]); } return res; } };