The Maximum-Subarray Problem

Suppose that you have been offered the opportunity to invest in the Volatile Chemical Corporation. Like the chemicals the company produces, the stock price of the Volatile Chemical Corporation is rather volatile. You are allowed to buy one unit of stock only one time and then sell it at a later date, buying and selling after the close of trading for the day. To compensate for this restriction, you are allowed to learn what the price of the stock will be in the future. Your goal is to maximize your profit.


The problem 1: you are allowed to complete transaction only once, how do you calculate the max profit you may get?

def max_profit_1(prices):
    max_profit = 0
    n = len(prices)
    if n > 1:
        min_price = prices[0]
        i = 1
        while i < n:
            if prices[i] > min_price:
                profit = prices[i] - min_price
                if profit > max_profit:
                    max_profit = profit
            else:
                if min_price > prices[i]:
                    min_price = prices[i]
            i += 1
    return max_profit

The problem 2: you are allowed to complete at most two transactions, how do you calculate the max profit you may get?

(Note:  you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again)).

def max_profit_2(prices):
    max_profit = 0
    n = len(prices)
    if n > 1:
        left = [0 for i in range(n)]
        right = [0 for i in range(n)]
        min_price = prices[0]
        i = 1
        while i < n:
            if prices[i] > min_price:
                profit = prices[i] - min_price
                if profit > max_profit:
                    max_profit = profit
            else:
                min_price = prices[i]
            left[i] = max_profit
            i += 1
        max_profit = 0
        i = n - 2
        max_price = prices[n - 1]
        while i >= 0:
            if prices[i] < max_price:
                profit = max_price - prices[i]
                if max_profit < profit:
                    max_profit = profit
            else:
                max_price = prices[i]
            right[i] = max_profit
            i -= 1
        i = 1
        max_profit = left[n - 1]
        while i < n - 2:
            profit = left[i] + right[i + 1]
            if profit > max_profit:
                max_profit = profit
            i += 1
    return max_profit

The problem 3: you are allowed to complete transactions at most k (>2) times, how do you calculate the max profit you may get?

(Note:  you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again)).

def max_profit_matrix(prices):
    n = len(prices)
    assert n > 1
    ret = [[0 for i in range(n)] for j in range(n - 1)]
    for i in range(n - 1):
        min_price = prices[i]
        max_profit = 0
        j = i + 1
        while j < n:
            if prices[j] > min_price:
                profit = prices[j] - min_price
                if profit > max_profit:
                    max_profit = profit
            else:
                min_price = prices[j]
            ret[i][j] = max_profit
            j += 1
    return ret

def max_profit_k(prices, k):
    assert k > 2
    max_profit = 0
    n = len(prices)
    if n > 1:
        M = max_profit_matrix(prices)
        cache = [[0 for i in range(n + 1)] for j in range(2)]
        max_price = prices[n - 1]
        max_profit = 0
        i = n - 2
        while i >= 0:
            if prices[i] < max_price:
                profit = max_price - prices[i]
                if profit > max_profit:
                    max_profit = profit
            else:
                max_price = prices[i]
            cache[0][i] = max_profit
            i -= 1
        prev = 0
        curr = 1
        r = 2
        while r <= k:
            for i in range(n - 1):
                j = i + 1
                max_profit = cache[prev][i]
                while j < n:
                    profit = M[i][j] + cache[prev][j + 1]
                    if profit > max_profit:
                        max_profit = profit
                    j += 1
                cache[curr][i] = max_profit 
            prev = curr
            curr = ((curr + 1) & 1)
            r += 1
        max_profit = cache[prev][0]
    return max_profit

The test code:

if __name__ == "__main__":
    prices = [100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97]
    assert max_profit_1(prices) == 43
    assert max_profit_2(prices) == 63
    assert max_profit_k(prices, 3) == 81
    assert max_profit_k(prices, 4) == 94

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值