买卖股票最佳时机(I II III IV 冷冻期,手续费)

共6个问题:

买卖股票最佳时机

买卖股票最佳时机 II

买卖股票最佳时机 III

买卖股票最佳时机 IV

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

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

分析:

  1. 只允许一次交易的最大收益(一次买进卖出)动态规划: dp[i] = max(dp[i-1], prices[i] - minval);
  2. 允许多次交易的最大收益(多次买进卖出)贪心算法:只要盈利就交易;
  3. 只允许有两次交易的最大收益(两次买进卖出)动态规划
    1) dp1[i] = max(dp[i-1], prices[i] - minval) 从前往后遍历,表示第1天到第i天之间的最大利润(通过是否在第i天卖出确认);
    2) dp2[i] = max(dp[i+1], maxval - prices[i]) 从后往前遍历,表示第i天到最后一天之间的最大利润(通过是否在第i天买进确认);
    3) res = max(dp1 + dp2),(dp1 + dp2)[i] 正好表示从第1天到最后一天经过两次交易的最大利润,我们的目标是知道令总利润最大的i。
  4. 只允许k次交易的最大收益(k次买进卖出)动态规划:
    local[i][j]表示第i天进行了j笔交易,且第j笔是在第i天完成的的最大收益;
    global[i][j]表示第i天进行了j笔交易的最大收益,是目前为止全局最优,不规定第j笔在哪天完成。则递推公式为:
    1) local[i][j] = max(global[i-1][j-1]+max(0, prices[i]-prices[i-1]), local[i-1][j]+prices[i]-prices[i-1])
    2) global[i][j] = max(local[i][j], global[i-1][j])
    3) 双重循环,计算最后取global[-1][-1]
    4) 注意当k大于天数时,直接用贪心算法。
    https://blog.csdn.net/linhuanmars/article/details/23236995
  5. 有冷冻期的最大交易(一次买卖后需要冷冻一天)动态规划
    sell[i]表示截至第i天,最后一个操作是卖时的最大收益;
    buy[i]表示截至第i天,最后一个操作是买时的最大收益;
    cool[i]表示截至第i天,最后一个操作是冷冻期时的最大收益;
    递推公式:
    sell[i] = max(buy[i-1]+prices[i], sell[i-1]) (第一项表示第i天卖出,第二项表示第i天冷冻)
    buy[i] = max(cool[i-1]-prices[i], buy[i-1]) (第一项表示第i天买进,第二项表示第i天冷冻)
    cool[i] = max(sell[i-1], buy[i-1], cool[i-1])
    https://www.cnblogs.com/grandyang/p/4997417.html
  6. 有手续费的最大交易(每买卖一次都会扣除一次手续费) 动态规划
    dp1[i]表示第i天手上有股票,dp2[i]表示第i天手上没有股票,递归方程:
    1) dp1[i] = max(dp1[i-1], dp2[i-1] - prices[i]) (第二项表示在第i天买入股票)
    2) dp2[i] = max(dp2[i-1], dp1[i-1] + prices[i] - fee) (第二项表示在第i天将股票卖出,需扣除手续费)

 

代码:

#买卖股票最佳时机I(只允许一次交易)
class Solution(object):
    def maxProfit(self, prices):
        n = len(prices)
        if n == 0:
            return 0
        dp = [0 for _ in range(n)]
        minval = prices[0]
        for i in range(1, n):
            dp[i] = max(dp[i-1], prices[i] - minval)
            minval = min(minval, prices[i])
        return dp[-1]

#买卖股票最佳时机II(允许多次交易)
class Solution:
    def maxProfit(self, prices):
        #贪心算法,只要出现盈利情况,就算作一次交易
        n = len(prices)
        if n == 0:
            return 0
        res = 0
        for i in range(1,n):
            res += max(0, prices[i]-prices[i-1])
        return res
    
#买卖股票最佳时机III(只允许两次交易)
class Solution:
    def maxProfit(self, prices):
        n = len(prices)
        if n < 2:
            return 0
        dp1 = [0 for _ in range(n)]
        dp2 = [0 for _ in range(n)]
        minval = prices[0]
        maxval = prices[-1]
        #前向
        for i in range(1,n):
            dp1[i] = max(dp1[i-1], prices[i] - minval)
            minval = min(minval, prices[i])
        #后向
        for i in range(n-2,-1,-1):
            dp2[i] = max(dp2[i+1], maxval - prices[i])
            maxval = max(maxval, prices[i]) 
        dp = [dp1[i] + dp2[i] for i in range(n)]
        return max(dp)
    
#买卖股票最佳时机IV(只允许k次交易)
class Solution:
    def maxProfit(self, k, prices):
        if k <= 0 or len(prices) == 0:
            return 0
        if k > len(prices):
            return self.greedy(prices)
        l = [[0 for _ in range(k+1)] for _ in range(len(prices))]
        g = [[0 for _ in range(k+1)] for _ in range(len(prices))]
        for i in range(1,len(prices)):
            diff = prices[i] - prices[i-1]
            for j in range(1,k+1):
                l[i][j] = max(g[i-1][j-1] + max(0, diff), l[i-1][j] + diff)
                g[i][j] = max(l[i][j], g[i-1][j])
        return g[-1][-1]
                      
    def greedy(self, prices):
        res = 0
        for i in range(1,len(prices)):
            res += max(0, prices[i]-prices[i-1])
        return res
    
#买卖股票最佳时机(含冷冻期)
class Solution:
    def maxProfit(self, prices):
        n = len(prices)
        if n == 0:
            return 0      
        sell = [0 for _ in range(n)]
        buy = [0 for _ in range(n)]
        cool = [0 for _ in range(n)]
        buy[0] = -prices[0]
        for i in range(1,n):
            sell[i] = max(buy[i-1] + prices[i], sell[i-1])
            buy[i] = max(cool[i-1] - prices[i], buy[i-1])
            cool[i] = max(sell[i-1], buy[i-1],cool[i-1])
        return sell[-1]
    
#买卖股票最佳时机(含手续费)
class Solution:
    def maxProfit(self, prices, fee):
        n = len(prices)
        if n < 2:
            return 0
        dp1 = [0 for _ in range(n)]#第i天手上有股票时的最大收益
        dp2 = [0 for _ in range(n)]#第i天手上无股票时的最大收益
        dp1[0] = -prices[0]
        for i in range(1,n):
            dp1[i] = max(dp1[i-1], dp2[i-1] - prices[i])
            dp2[i] = max(dp2[i-1], dp1[i-1] + prices[i] - fee)
        return dp2[n-1]

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值