Likou 123. The best time to buy and sell stocks III-dynamic programming two-dimensional equation

123. The best time to buy and sell stocks III

Given an array, its i-th element is the price of a given stock on the i-th day.

Design an algorithm to calculate the maximum profit you can get. You can complete up to two transactions.

Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

示例 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。

Problem solution: two-dimensional dynamic programming

First of all, we must understand that there are many states of the subject at this time , we might as well list all possible states first.
It can be seen from the question that we first perform a clear state operation, that is, this question can be divided into five states:
1. No operation is performed.
2. Buy for the first time.
3. Sell for the first time.
4. The second purchase.
5. The second sale.

After enumerating these several states, we can obviously know that we should adopt dynamic programming to solve the problem. That is to say, for the big problem required by the title, we first divided it into five states , and since the number of days is also a factor that affects the left and right, we can then think about each state separately, so that each state can list a two Dimensional state transition equation :

Let dp[i][j] be the amount of money left when the i-th day is in state j.

State 1: The equation is dp[i][0]=dp[i-1][0]

Because the five states come one by one in order, you cannot enter the next state when the previous state is not completed. Therefore, if there is no operation on the i-th day, there must be no operation on the previous day, because the right side of the transfer equation should be the left side. The previous state of the state, so there is no state at this time, only no operation.

State 2: The equation is dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i])

Because the status of the i-th day is 1, that is, the state of buying, but it may be bought on the i-th day, or it may not be bought on the i-th day, that is, the buying operation is completed on the i-1 day, so choose . Who do you choose? Naturally, the total amount of money is still too large when the money is spent after buying it.
Natural states three, four, and five can be listed in the same way.

From the above finding the state transition equation corresponding to each state, we have actually completed the decomposition of several individual problems into several sub-problems , so we still need to perform the last step, which is to determine the boundary . As this problem can be seen from the equation , The back state is derived from the previous state, so we have to determine the front boundary.
Obviously, it can be seen that dp[0][0]=0
and dp[0][1]=-price[0]
. For dp[0][2], it means the state of selling on the first day. So how does he proceed to sell state? That is, he bought first and then sold on this day, which is naturally bought at the original price, and then sold at the original price, so the profit is 0;
then the bottom 4 status is also, that is, buy and then sell, buy and then sell.
dp[0][3]=-prices[0];
dp[0][4]=0;
all can be known.

Therefore, the code is as follows:

#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];
}

Guess you like

Origin blog.csdn.net/xiangguang_fight/article/details/112125611