1057 stock trading IV (state machine model)

Keywords: Algorithm

1. Problem Description:

Given an array of length N, the ith number in the array represents the price of a given stock on day i. Design an algorithm to calculate the maximum profit you can make. You can complete up to k transactions. Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again). A buy and sell is a transaction.

Input format

The first line contains integers N and k, indicating the length of the array and the maximum number of transactions you can complete. The second line contains N positive integers no more than 10000, representing the complete array.

Output format

Output an integer representing the maximum profit.

Data range

1 ≤ N ≤ 10 ^ 5,
1 ≤ k ≤ 100

Input example 1:

3 2
2 4 1

Output example 1:

2

Input example 2:

6 2
3 2 6 5 0 3

Output example 2:

7

Example explanation

Example 1: buy on the first day (stock price = 2) and sell on the second day (stock price = 4). This exchange can make a profit = 4 - 2 = 2.
Example 2: buy on day 2 (stock price = 2) and sell on day 3 (stock price = 6). This exchange can make a profit = 6 - 2 = 4. Then, buy on the 5th day (stock price = 0) and sell on the 6th day (stock price = 3). This exchange can make a profit = 3-0 = 3. Total profit 4 + 3 = 7
Source: https://www.acwing.com/problem/content/description/1059/

2. Train of thought analysis:

The stock problem belongs to the classic state machine problem. The state machine actually describes a process, which describes a complex process as the transfer between states. According to the description of the topic, we can draw the corresponding state machine description, as shown in the figure below (the state machine description is the core). We can declare a three-dimensional array or three-dimensional list, where dp[i][j][0] It indicates that there were j transactions in the previous I day, and dp[i][j][0] indicates that there were j transactions in the previous I day. Therefore, the general status is further divided into two states. Because one purchase and one sale are combined into one transaction, we can set the time of purchase as the beginning of a transaction and the time of sale as the end of a transaction, In this way, we only need to count the maximum value of the empty state. Because N and k are relatively large, the multiplication result is also relatively large. Moreover, considering that only two states of a certain dimension are used each time, we can use the rolling array to optimize the empty complexity.

3. The code is as follows:

python (timeout code):

if __name__ == "__main__":
    n, k = map(int, input().split())
    a = list(map(int, input().split()))
    INF = 10 ** 10
    dp = [[[-INF] * 2 for i in range(k + 1)] for j in range(n + 1)]
    for i in range(n + 1): dp[i][0][0] = 0
    for i in range(1, n + 1):
        for j in range(1, k + 1):
            dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1] + a[i - 1])
            dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - a[i - 1])
    res = 0
    for i in range(1, k + 1):
        res = max(res, dp[n][i][0])
    print(res)

Scroll array optimization:

if __name__ == "__main__":
    n, k = map(int, input().split())
    a = list(map(int, input().split()))
    INF = 10 ** 10
    # It can be found that only two states are used, so we can use the rolling array to solve the problem, which can avoid the time-consuming problem of python declaring a large multidimensional list
    dp = [[[-INF] * 2 for i in range(k + 1)] for j in range(2)]
    for i in range(n + 1): dp[i & 1][0][0] = 0
    for i in range(1, n + 1):
        for j in range(1, k + 1):
            dp[i & 1][j][0] = max(dp[(i - 1) & 1][j][0], dp[(i - 1) & 1][j][1] + a[i - 1])
            dp[i & 1][j][1] = max(dp[(i - 1) & 1][j][1], dp[(i - 1) & 1][j - 1][0] - a[i - 1])
    res = 0
    for i in range(1, k + 1):
        res = max(res, dp[n & 1][i][0])
    print(res)

Posted by Undead_Zeus on Sun, 19 Sep 2021 10:44:29 -0700