151. 买卖股票的最佳时机 III

描述

假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。

样例

给出一个样例数组 [4,4,6,1,1,4,2,5], 返回 6

思路:

分为五个阶段,如下图所示。


股票3.png

考虑dp[n][k]为前n支股票在阶段k能获得的最大利润。
如果k为1,3,5,意味着此时并没有持有股票。那么前一状态n-1支股票只有两种取法,一种是前n-1支股票本来就在k的位置,即遍历到前n-1支股票仍然没有股票,没有利润,因此dp[n][k]=dp[n-1][k]。另一种是n-1时持有股票,即必然处于k-1的状态,到n时正好卖出,即dp[n][k]=dp[n-1][k-1]+prices[n-1]-prices[n-2]。二者取最大值。
如果k为2,4,意味此时持有股票。那么前一状态n-1支股票有三种取法。
1.前n-1支股票也处于状态k,则此时利润为dp[n][k]=dp[n-1][k]+prices[n-1]-prices[n-2]。
2.前n-1支股票处于状态k-1,没有股票,则在n-1时刻买入,此时dp[n][k]=dp[n-1][k-1]。
3.前n-1支股票处于状态k-2,即第一次持有股票,卖出去后再买入当天的股票,此时dp[n][k]=dp[n-1][k-2]+prices[n-1]-prices[n-2]。
三者取最大值。
结果返回没有持有股票时候的最大值就行了。具体实现如下。

class Solution {
public:
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    int maxProfit(vector &prices) {
        // write your code here
        int n=prices.size();
        if(!n)
        {
            return 0;
        }
        vector> dp(n+1,vector(6,0));
        dp[0][1]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=5;j+=2)
            {
                dp[i][j]=dp[i-1][j];
                if(j-1>0 && i>=2)
                {
                    dp[i][j]=max(dp[i][j],dp[i-1][j-1]+prices[i-1]-prices[i-2]);
                }
            }
            for(int j=2;j<=5;j+=2)
            {
                dp[i][j]=dp[i-1][j-1];
                if(i>=2)
                {
                    dp[i][j]=max(dp[i][j],dp[i-1][j]+prices[i-1]-prices[i-2]);
                }
                if(j-2>0 && i>=2)
                {
                    dp[i][j]=max(dp[i][j],dp[i-1][j-2]+prices[i-1]-prices[i-2]);
                }
            }
        }
        return max(dp[n][1],max(dp[n][3],dp[n][5]));
        
    }
};

你可能感兴趣的:(151. 买卖股票的最佳时机 III)