Day 41 动态规划 Part09 开始炒股

动态规划解题步骤

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

121. 买卖股票的最佳时机

这道题虽然自己做出来了,但是做了后面的题再回头看它就有了不一样的理解。curMin更重要的代表了一种状态,代表遍历到当前时间时最低的股价。本质上curMin也应该是一个和prices等长的数组,表示了每天的状态(这就是这道题动态规划思路体现的位置),只是由于每天的状态都由前一天完全确定,且我们最终也只需要最后一天的结果,所以空间上可以优化成O(1)

class Solution {
    public int maxProfit(int[] prices) {
        int curMin = prices[0];
        int max = 0;
        for(int i = 0; i < prices.length; i++){
            int profit = prices[i] - curMin;
            max = Math.max(max, profit);
            curMin = Math.min(curMin, prices[i]);
        }
        return max;
    }
}

122. 买卖股票的最佳时机 II

这道题给了我一种贪心的感觉,收获每个正收益即可。

class Solution {
    public int maxProfit(int[] prices) {
        int max = 0;
        for(int i = 1; i < prices.length; i++)
            max += Math.max(0, prices[i] - prices[i-1]);
        return max;
    }
}

动态规划的版本代码先放在这里,看了下一道题再看就非常易懂了。

class Solution {  //动态规划版本
    public int maxProfit(int[] prices) {
        int[] stat = new int[2];
        stat[0] = Integer.MIN_VALUE;
        for(int i = 0; i < prices.length; i++){
            stat[0] = Math.max(stat[0], stat[1] - prices[i]);
            stat[1] = Math.max(stat[1], stat[0] + prices[i]);
        }
        return stat[1];
    }
}

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

这道题和188. 买卖股票的最佳时机 IV可以说一模一样,就按照k次买入卖出来做,对于本题取k=2即可。

最主要的就是要描述每天的状态,每天可以有多少种状态呢?对于最多k次交易,我们可以想到有第1次买入,第1次卖出 ... 第k次买入,第k次卖出共有2*k次状态。因此dp数组形状应该是k * n,确定了dp数组就去考虑如何更新dp数组就好了。

这里更详细解释下dp[i][j]的含义:第j天状态为i时的最大利润,一定仔细仔细理解这句话。

注意看下面这个表格中所有的状态:第一次买入代表当前还持有第一次买入的股票,可以是当天买的,也可以是之前买入的。其他状态的理解也是这样。

day1 2 ... day n
第一次买入
第一次卖出
...
第k次买入
第k次卖出
// 188
class Solution {
    public int maxProfit(int k, int[] prices) {
        int[] states = new int[2*k];
        Arrays.fill(states, Integer.MIN_VALUE);
        for(int i = 0; i < prices.length; i++){
            for(int j = 0; j < k; j++){
                states[2*j] = Math.max(states[2*j], 
                    2*j == 0 ? -prices[i] : states[2*j-1] - prices[i]); 
                states[2*j+1] = Math.max(states[2*j+1], 
                    states[2*j] + prices[i]);
            }
        }
        return states[2*k-1];
    }
}


class Solution {
    public int maxProfit(int[] prices) {
        int[] stat = new int[4];
        Arrays.fill(stat, Integer.MIN_VALUE);
        for(int i = 0; i < prices.length; i++){
            stat[0] = Math.max(stat[0], -1 * prices[i]);
            stat[1] = Math.max(stat[1], prices[i] + stat[0]);
            stat[2] = Math.max(stat[2], stat[1] - prices[i]);
            stat[3] = Math.max(stat[3], prices[i] + stat[2]);
        }
        return stat[3];
    }
}
posted @ 2024-08-12 23:22  12点不睡觉还想干啥?  阅读(39)  评论(0)    收藏  举报