leetcode309

最佳买卖股票时机含冷冻期

题目:

每天可以选择可以买入卖出或者继续持有一笔股票,只有卖出之后才能重新买入一笔股票,并且卖出股票之后的第一天处于冷冻期,不能买入股票。问如何才能拿到最大收益?

思路:每一天的收益状态都是依赖于前一天收益状态的。因此可以对每一天分为三种情况:

情况1:持有该笔股票的最大收益,这一笔股票可以是今天买入的,也可以是本来就有的。

情况2:不持有该笔股票并且处于冷冻期的最大收益,也就是昨天卖出了这笔股票。

情况3:不持有该笔股票并且不处于冷冻期的最大收益,昨天可能是冷冻期也可能不是。

可以定义一个二维数组来进行转态转移。

得到如下状态转移方程:

dp[i][0] = max(dp[i-1][0], dp[i][2] - prices[i])

dp[i][1] = dp[i-1][0] + prices[i]

dp[i][2] = max(dp[i-1][2], dp[i-1][1])

func maxProfit(prices []int) int {
    days := len(prices)
    dp := make([][]int, days)
    for i:=0; i<days; i++{
        dp[i] = make([]int, 3)
    }
    dp[0][0] = -prices[0]

    for i:=1 ;i<days; i++{
        dp[i][0] = max(dp[i-1][0], dp[i-1][2]- prices[i])
        dp[i][1] = dp[i-1][0] + prices[i]
        dp[i][2] = max(dp[i-1][1], dp[i-1][2])
    }
    return max(dp[days-1][1], dp[days-1][2])
}
func max(a, b int) int{
    if a > b{
        return a
    }
    return b
}

优化空间:

由于每一个状态i都依赖于i-1,故可以使用三个变量来代替就行,不必要开一个数组,可以把空间降到O(1)。

class Solution {
    public int maxProfit(int[] prices) {
        int x1 = -prices[0] ,x2 =0,x3 =0;
        for(int i = 1; i< prices.length; i++){
            int y1 = Math.max(x1, x3 - prices[i]);
            int y2 = x1 + prices[i];
            int y3 = Math.max(x2, x3);
            x1 = y1;
            x2 = y2;
            x3 = y3;

        }
        return Math.max(x2 , x3);
    }
}

总结一下动态规划的解题步骤:

1. 确定dp数组及其下标含义。

2. 求出状态转移方程。

3. dp数组如何初始化。

4. 确定遍历顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值