给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。

    设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

    你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
    卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

    分析:这道题相较于正篇,多了个冷冻期,我认为难度提升了不少,重点是要对这其中的弯弯绕绕要弄清楚。
    有了冷冻期之后,状态就变成了4种,对这4种要特别清晰,不能被绕晕!
    状态1:持有股票或刚买入股票
    状态2:卖出股票的第一天 //说明:既然说是第一天,那么今天是必然会卖股票的,递推公式中不用和前一天进行比较
    状态3:无票在手 //此状态为卖出股票的第二天之后或是一直未持有股票的状态
    状态4:冷冻期 //说明:冷冻期也是一个固定状态而不是递推状态,它是一个确定值而不是比较值

    状态转移:
    状态1: 有3个状态可以转到状态1:
    1.不动
    2.昨天是冷冻期,可买入股票
    3.昨天是状态3,即自由状态,可买入股票
    那么递推公式为:
    dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][3]-prices[i],dp[i-1][4]-prices[i]))
    状态2:只有状态1可以得到状态1,且其为确定值:
    dp[i][1]=dp[i-1][0]+prices[i]
    状态3:有2个状态可以转到状态3:
    1.不动
    2.冷冻期转入
    则递推公式为:
    dp[i][3]=Math.max(dp[i-1][3],dp[i-1][4])
    状态4:只有前一天的状态2可以得到状态1,故其为确定值:
    dp[i][4]=dp[i-1][2]
    初值:与之前相同,直接将第一天的买入设为-prices[i]即可

    返回值:由于状态3的更新会晚一天,所以要取状态2与状态3的最大值;

    参考代码:
    public int maxProfit(int[] prices) {
    int[][] dp = new int[prices.length][4];
    dp[0][0]=-prices[0];
    for(int i=1;i dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][2]-prices[i],dp[i-1][3]-prices[i]));
    dp[i][1]=dp[i-1][0]+prices[i];
    dp[i][2]=Math.max(dp[i-1][1],dp[i-1][2]);
    dp[i][3]=dp[i-1][1];
    }
    return Math.max(dp[prices.length-1][1],dp[prices.length-1][2]);
    }