【代码随想录——动态规划——第五周——买卖股票】

1.买卖股票的最佳时机

在这里插入图片描述

1.1 贪心方法

func maxProfit(prices []int) int {
    // 低买高卖
    minGetPrice := prices[0]
    maxSaleProfit := 0
    for i:=0;i<len(prices);i++{
    	// 检查是否低于最低买入价
        if prices[i]<minGetPrice{
            minGetPrice = prices[i]
         // 尝试在这里卖出
        }else if maxSaleProfit<prices[i]-minGetPrice{
            maxSaleProfit = prices[i]-minGetPrice
        }
    }
    return maxSaleProfit
}

1.2 动态规划的方法

func maxProfit(prices []int) int {
    length := len(prices)
    if length == 0 {
        return 0
    }
    dp := make([][]int,length)
    for i := 0;i<length;i++{
        dp[i] = make([]int,2)
    }
    dp[0][0] = -prices[0]
    dp[0][1] = 0

    for i := 1; i < length; i++ {
        //dp[i][0]用来表示第i天之前能买入的最低价,使用负数代表买股票后的负债,负债越小越好,所以这里选择最大值
        dp[i][0] = max(dp[i-1][0], -prices[i])
        //dp[i][1]用来表示在第前i天卖出能得到的最高理论
        dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
    }
    return dp[length-1][1]
}

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

在这里插入图片描述
不同点在于:你可以多次买入卖出股票,但是买入一定在卖出之前。买入之后不可以再买入股票,必须先卖出。
这里用一个[2]int来存储两个不同的情况,[i][0]用来表示第i日持有股票的情况下最大的利润,[i][0]表示第i日不持有股票的情况下的最大利润。

func maxProfit(prices []int) int {
    dp := make([][]int,len(prices))
    for i:=0; i<len(prices); i++{
        dp[i] = make([]int,2)
    }  
    dp[0][0] = -prices[0]
    dp[0][1] = 0
    for i:=1;i<len(prices);i++{
        dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i])
        dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
    }
    return dp[len(prices)-1][1]
}

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

在这里插入图片描述
思路:这里我们给每个dp设置了5个状态。每个状态都依赖于前一个状态进行推导。

func maxProfit(prices []int) int {
    dp := make([][]int,len(prices))
    /**
    没有操作
    第一次持有股票
    第一次不持有股票
    第二次持有股票
    第二次不持有股票
    **/
    for i:=0; i<len(prices); i++{
        dp[i] = make([]int,5)
    }

    dp[0][0] = 0
    dp[0][1] = -prices[0]
    dp[0][2] = 0
    dp[0][3] = -prices[0]
    dp[0][4] = 0
    for i:=1;i<len(prices);i++{
        dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i])
        dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i])
        dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i])
        dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i])
    }
    maxProfit := 0
    for i:=1;i<5;i++{
        if dp[len(prices)-1][i]>maxProfit{
            maxProfit = dp[len(prices)-1][i]
        }
    }
    return maxProfit
}

4.买卖股票的最佳时机IV

在这里插入图片描述
没什么好说的,直接看代码

func maxProfit(k int, prices []int) int {
    dp := make([][]int,len(prices))
    /**
    没有操作
    第一次持有股票
    第一次不持有股票
    .....
    第k次持有股票
    第k次不持有股票
    **/
    for i:=0; i<len(prices); i++{
        dp[i] = make([]int,2*k+1)
    }
    // 初始化
    for i:=0;i<k;i++{
        dp[0][i*2+1] = -prices[0]
    }
    // 开始递推公式
    for i:=1;i<len(prices);i++{
        for j:=1;j<2*k+1;j++{
            if j%2==0{
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+prices[i])
            }else{
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]-prices[i])
            }
        }
    }
    maxProfit := 0
    for i:=1;i<2*k+1;i++{
        if dp[len(prices)-1][i]>maxProfit{
            maxProfit = dp[len(prices)-1][i]
        }
    }
    return maxProfit
}

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

在这里插入图片描述

func maxProfit(prices []int) int {
	dp := make([][]int, len(prices))
	/**
	  状态总数n
	  状态0:持有股票状态
	  状态1:不持有股票,且不在冷冻区
	  状态2:今天卖出股票
	  状态3:今天为冷冻区
	  **/
	n := 4
	for i := 0; i < len(prices); i++ {
		dp[i] = make([]int, n)
	}
	// 初始化
	dp[0][0] = -prices[0]
	dp[0][1] = 0
	dp[0][2] = 0
	dp[0][3] = 0
	//fmt.Println(dp)
	//递推公式
	for i := 1; i < len(prices); i++ {
		//今天买股票,则前一天为状态0、1、3
		dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1])-prices[i])
		dp[i][1] = max(dp[i-1][1], dp[i-1][3])
		dp[i][2] = dp[i][0] + prices[i]
		dp[i][3] = dp[i-1][2]
		//fmt.Println(dp)
	}
	//返回结果
	profit := 0
	for i := 0; i < n; i++ {
		if profit < dp[len(prices)-1][i] {
			profit = dp[len(prices)-1][i]
		}
	}
	return profit
}

6.买卖股票的最佳时机含手续费

在这里插入图片描述

func maxProfit(prices []int, fee int) int {
    dp := make([][]int,len(prices))
    /**
    状态数n=2
    0:持有股票
    1:不持有股票
    **/
    n := 2
    for i:=0;i<len(prices);i++{
        dp[i]=make([]int,n)
    }
    //初始化
    dp[0][0] = -prices[0]
    dp[0][1] = 0
    //递推函数
    for i:=1;i<len(prices);i++{
        dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i])
        dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i]-fee)
    }
    //返回结果
    return max(dp[len(prices)-1][0],dp[len(prices)-1][1])
}
  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值