力扣123. 买卖股票的最佳时机 III--动态规划二维方程

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

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
     随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
示例 2:

输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。   
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。   
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:

输入: [7,6,4,3,1] 
输出: 0 
解释: 在这个情况下, 没有交易完成, 所以最大利润为 0。

题解:二维动态规划

首先要明白题目此时状态有很多种,我们不妨先列举出所有可能存在的状态。
由题可知,我们先进行明确状态操作,即此题可以分为五个状态:
1.不进行任何操作。
2.第一次买入。
3.第一次卖出。
4.第二次买入。
5.第二次卖出。

在列举出这几个状态后,我们明显可以知道应该采取动态规划的方式进行求解。即对于题目所要求的这个大问题,我们先分为了五个状态,且由于天数也是一个起到影响左右的因素,我们可以接着分别思考一下每个状态,使得每一个状态都能列出一个二维的状态转移方程

设dp[i][j]为第i天为状态j时剩余的金钱数量。

状态一:方程为dp[i][0]=dp[i-1][0]

因为五个状态是按照顺序一个一个来的,不能在前面状态未完成的情况下进入下一个状态,因此第i天无操作的话其前一天必然也只能无操作,因为转移方程右边应该是左边的状态的前一个状态,所以此时没状态了,只能无操作了。

状态二:方程为 dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i])

因为第i天的状态为1,即买入的状态,但可能是第i天买的,也可能不是第i天买的,即第i-1天就完成买入操作了,所以要进行选择。选谁呢?自然是选在买入后即花钱后此时金钱总数还是偏大的了。
自然状态三,四,五同理可以列出。

由上述寻找每个状态对应的状态转移方程,我们其实已经完成了将若干的单独的问题分解为几个子问题,所以我们还需要进行最后一步操作,即确定边界,由于此题从方程可以看出,后状态由前状态得出,所以我们要进行确定前边界。
明显可知dp[0][0]=0
而dp[0][1]=-price[0]
而对于dp[0][2],即他代表的意思是第一天进行卖出状态。那么他怎么进行卖出状态呢?即这一天里他先买然后又卖了,这自然是原价买了,又原价卖了,所以利润为0;
那么下方4状态也是,即买了再卖买了再卖。
dp[0][3]=-prices[0];
dp[0][4]=0;
都可知。

因此可知代码如下:

#define max(a,b) ((a)>(b)?a:b)
int maxProfit(int* prices, int pricesSize){
    if(pricesSize==0||pricesSize==1)
        return 0;
    int dp[pricesSize][5];
    dp[0][0]=0;
    dp[0][1]=-prices[0];
    dp[0][2]=0;
    dp[0][3]=-prices[0];
    dp[0][4]=0;
    for(int i=1;i<pricesSize;i++)
    {
        dp[i][0]=dp[i-1][0];//因为五个操作是按步骤一个一个来的,0是第一个状态,所以其前面没有状态了
        dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
        dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i]);
        dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i]);
        dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i]);
    }
    return dp[pricesSize-1][4];
}

你可能感兴趣的:(Leetcode每日刷题,#,动态规划,动态规划,算法)