首页 > 代码库 > 188. Best Time to Buy and Sell Stock IV

188. Best Time to Buy and Sell Stock IV

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most k transactions.

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

Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.

 

用local[i][j]表示到达第i天时,最多进行j次交易的局部最优解;用global[i][j]表示到达第i天时,最多进行j次的全局最优解。它们二者的关系如下(其中diff = prices[i] – prices[i – 1]):

local[i][j] = max(global[i – 1][j – 1] , local[i – 1][j] + diff)
global[i][j] = max(global[i – 1][j], local[i][j])

local[i][j]和global[i][j]的区别是:local[i][j]意味着在第i天一定有交易(卖出)发生,当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即local[i][j]=local[i-1][j]+diff;当第i天的价格不高于第i-1天(即diff<=0)时,那么local[i][j]=global[i-1][j-1]+diff,而由于diff<=0,所以可写成local[i][j]=global[i-1][j-1]。global[i][j]就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:如果第i天没有交易(卖出),那么global[i][j]=global[i-1][j];如果第i天有交易(卖出),那么global[i][j]=local[i][j]。

 

//if(k >= days)  go to II
//k < days
//local[0][0] = 0; global[0][0]
//local[i][j] = Math.max(local[i-1][j] + differ, global[i-1][j-1]); 在第i天一定进行交易 diff >0
//global[i][j] = Math.max(local[i][j], global[i-1][j]); 在第i 天进行交易,或者不进行交易

public class Solution {
    public int maxProfit(int k, int[] prices) {
        if(prices == null || prices.length <= 1 || k==0) return 0;
        int days = prices.length;
        if(k >= days) return getMaxProfit(prices); // question II
        int local[][] = new int[days][k+1];
        int global[][] = new int[days][k+1];
        local[0][0] = 0;
        global[0][0] = 0;
        for(int i = 1; i < days ; i++){
            int diff = prices[i] - prices[i-1];
            for(int j = 1 ; j <= k ; j ++){
                local[i][j] = Math.max(local[i-1][j] + diff, global[i-1][j-1]);
                global[i][j] = Math.max(local[i][j], global[i-1][j]);
            }
        }
        return global[days-1][k];
    }
    public int getMaxProfit(int[] prices) {
        int total = 0;
        for(int i = 1; i < prices.length; i++){
            if(prices[i] > prices[i-1]) total += prices[i]-prices[i-1];
        }
        return total;
    }
}

 

188. Best Time to Buy and Sell Stock IV