day47【代码随想录】动态规划之买卖股票的最佳时机III、买卖股票的最佳时机IV、最佳买卖股票时机含冷冻期、买卖股票的最佳时机含手续费

news2024/9/22 17:31:32

文章目录

  • 前言
  • 一、买卖股票的最佳时机III(力扣123)
  • 二、买卖股票的最佳时机IV(力扣188)
  • 三、最佳买卖股票时机含冷冻期(力扣309)
  • 四、买卖股票的最佳时机含手续费(力扣714)
  • 股票买卖问题总结


前言

1、买卖股票的最佳时机III
2、买卖股票的最佳时机IV
3、最佳买卖股票时机含冷冻期
4、买卖股票的最佳时机含手续费


一、买卖股票的最佳时机III(力扣123)

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
8888在这里插入图片描述
分析:
与之前的区别在于最多可以买卖两次
动规五部曲
1、dp[]数组以及下标含义
dp[i][0]:不操作
dp[i][1]:第一次持有
dp[i][2]:第一次不持有
dp[i][3]:第二次持有
dp[i][4]:第二次不持有
2、递推公式
dp[i][0] = dp[i-1][0]
dp[i][1] = Math.max(dp[i-1][1],-price[i])
dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1]+price[i])
dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2]-price[i])
dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+price[i])
3、初始化
dp[0][0] = 0;
dp[0][1] = -price[0];
dp[0][2] = 0;
dp[0][3] = -price[0];
dp[0][4] = 0;
4、遍历顺序
从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

二维dp数组

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

优化版:(滚动数组):

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

二、买卖股票的最佳时机IV(力扣188)

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
在这里插入图片描述
分析:
与之前的区别在于最多可以买卖k次
根据上一题所表现出来的规律:
1、dp[]数组以及下标含义
dp[i][0]:不操作
dp[i][1]:第一次持有
dp[i][2]:第一次不持有
dp[i][3]:第二次持有
dp[i][4]:第二次不持有
……
当有k次买卖时,奇数表示买入,偶数表示卖出。
初始化

for(int j=0;j<2*k+1;j++){
	if(j%2==1){
		dp[0][j] = -prices[0];
	}
}

递推公式
dp[i][0] = dp[i-1][0]
dp[i][1] = Math.max(dp[i-1][1],-price[i])
dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1]+price[i])
dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2]-price[i])
dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+price[i])

for(int i = 1; i<prices.length; i++){
	for(int j=1; j<2*k+1;j=j+2){
		dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-1]-prices[i]);
		dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][j]+prices[i]);
	}
}
class Solution {
    public int maxProfit(int k, int[] prices) {
        int[][] dp = new int[prices.length][2*k+1];
        for(int j=1;j<2*k+1;j++){
            if(j%2==1) dp[0][j] = -prices[0];
        }

        for(int i=1;i<prices.length;i++){
            for(int j=0;j<2*k-1;j=j+2){
                dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][j]-prices[i]);
                dp[i][j+2] = Math.max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
            }
        }
        return dp[prices.length-1][2*k];
    }
}

在这里插入图片描述

三、最佳买卖股票时机含冷冻期(力扣309)

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

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

你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
在这里插入图片描述
动规五部曲:
1、dp[]数组以及下标含义
dp[i][0]:持有股票的状态
dp[i][1]:保持卖出股票的状态
dp[i][2]:卖出股票状态
dp[i][3]:冷冻期

为什么要把 不持有股票状态拆分为两个部分【保持卖出股票的状态、卖出股票状态】,因为有冷冻期。必须前一天是卖出股票的状态,那么下一天才能是冷冻期

2、递推公式
持有股票状态:
1、i-1天就持有:dp[i][0] = dp[i-1][0];
2、冷冻期之后买入股票:dp[i][0] = dp[i-1][3] - prices[i];
3、冷冻期之后一直没有操作,一直都是保持卖出股票状态,直到第i天买入:dp[i][0] = dp[i-1][1] - prices[i];
因此:dp[i][0] = Math.max(dp[i-1][0], dp[i-1][3] - prices[i], dp[i][0] = dp[i-1][1] - prices[i])

保持卖出股票状态:
1、前一天就是保持卖出股票的状态:dp[i][1] = dp[i-1][1];
2、前一天是冷冻期,dp[i][1] = dp[i-1][3]
因此:dp[i][1] = Math.max(dp[i-1][1] , dp[i-1][3])

卖出股票状态:
1、前i-1天持有股票状态,第i天卖出股票.dp[i][2] = dp[i-1][0]+prices[i];
因此:dp[i][2]=dp[i-1][0]+prices[i];

冷冻期状态
1、前一天卖出股票状态,第i天就是冷冻期 dp[i][3] = dp[i-1][2]
因此:dp[i][3] = dp[i-1][2];

3、初始化
dp[0][0] = -prices[0];
dp[0][1] 在dp[i][0] = Math.max(dp[i-1][0], dp[i-1][3] - prices[i], dp[i][0] = dp[i-1][1] - prices[i]) 这个状态下会用到,假设i=1带入之后:
dp[1][0] = max(dp[0][0],dp[0][3]-prices[1], dp[0][1]-prices[1]);
dp[0][1] = 0;

dp[0][2] = 0;
dp[0][3] = 0;

4、遍历顺序
从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

class Solution {
    public int maxProfit(int[] prices) {
        int[][] dp = new int[prices.length][4];
        //初始化
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = 0;
        dp[0][3] = 0;
        //遍历
        for(int i=1;i<prices.length;i++){
            //持有股票的状态
            dp[i][0] = Math.max(Math.max(dp[i-1][0],dp[i-1][1]-prices[i]),dp[i-1][3]-prices[i]);
            //保持卖出股票的状态
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][3]);
            //卖出股票状态
            dp[i][2] = dp[i-1][0]+prices[i];
            //冷冻期
            dp[i][3] = dp[i-1][2];
        }
        return Math.max(Math.max(dp[prices.length-1][3],dp[prices.length-1][2]),dp[prices.length-1][1]);
    }
}

在这里插入图片描述

四、买卖股票的最佳时机含手续费(力扣714)

给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
在这里插入图片描述
在之前有用贪心算法进行求解:
贪心算法求解

分析:
买卖股票的最佳时机II 可以进行多次买卖,但多了手续费

dp[i][0]:表示第i天持有股票所得现金。
dp[i][1]:表示第i天不持有股票所得最多现金
dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i]-fee)
dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i]);

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

优化后(一维滚动数组)

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

在这里插入图片描述


股票买卖问题总结

买卖股票的最佳时机(力扣121) 只能买卖一次
dp[i][0]:持有股票的状态
dp[i][1]:不持有股票的状态
dp[0][0] = -prices[0];
dp[0][1] = 0;
dp[i][0] = max(dp[i-1][0], -prices[i])
dp[i][1] = max(dp[i-1][1] , dp[i-1][0]+prices[i])

买卖股票的最佳时机||(力扣122)可以买卖多次
dp[i][0]:持有股票的状态
dp[i][1]:不持有股票的状态
dp[0][0] = -prices[0];
dp[0][1] = 0;
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])
细微变化在于持有股票状态的递推过程

买卖股票的最佳时机|||(力扣123)最多买卖2次
dp[i][0] 不操作
dp[i][1]:第一次持有股票状态
dp[i][2]:第一次不持有股票状态
dp[i][3]:第二次持有股票状态
dp[i][4]:第二次不持有股票状态
初始化
dp[0][0]= 0
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[i][0] = dp[i-1][0]
dp[i][1] = max(dp[i-1][1],-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])

买卖股票的最佳时机IV(力扣188) 最多买卖k次
dp[i][0] 不操作
dp[i][1]:第一次持有股票状态
dp[i][2]:第一次不持有股票状态
dp[i][3]:第二次持有股票状态
dp[i][4]:第二次不持有股票状态
……
0 ----- 2*k
奇数是持有股票状态
偶数是卖出股票状态
初始化时:
if(j%2==1) dp[0][j] = -prices[0];
奇数时:dp[i][j] = max(dp[i-1][j],dp[i-1][j-1] - prices[i])
偶数时:dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] +prices[i])

最佳买卖股票时机含冷冻期(力扣309) 买卖多次,卖出后有一天是冷冻期
dp[i][0]:持有股票的状态
dp[i][1]:保持卖出股票的状态
dp[i][2]:卖出股票的状态
dp[i][3]:冷冻期
初始化
dp[0][0] = -prices[0];
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i], dp[i-1][3]- prices[i])
dp[i][1] = max(dp[i-1][1], dp[]i-1[3])
dp[i][2] = dp[i-1][0]+prices[i]
dp[i][3] = dp[i-1][2]

买卖股票的最佳时机含手续费(力扣714)买卖多次,每次都有手续费
dp[i][0]:持有股票的状态
dp[i][1]:不持有股票的状态
dp[0][0] = -prices[0]-fee;
dp[0][1] = 0;
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i]-fee)
dp[i][1] = max(dp[i-1][1] , dp[i-1][0]+prices[i])
细微变化在于多减去手续费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/357351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

office365 word 另存为 pdf 的注意事项和典型设置

0. 操作环境介绍 Office 版本&#xff1a;Office 365 版本 不同版本的操作可能有所不同 1. 基本操作 – 另存为 pdf 【文件】 --> 【另存为】&#xff0c;选择适当的文件路径、文件名保存类型选择【PDF】点击【保存】 1. 导出的pdf包含目录标签 word中&#xff0c;可使用…

Head First设计模式---1.策略模式

4.1策略模式&#xff1a; 策略模式是一种行为设计模式&#xff0c; 它能让你定义一系列算法&#xff0c; 并将每种算法分别放入独立的类中&#xff0c; 以使算法的对象能够相互替换。 问题 一天&#xff0c;我们需要做一个鸭子游戏&#xff0c;游戏中会出现各种鸭子&#xff…

掘金数据时代2022年度隐私计算评选活动火热报名中!

开放隐私计算 开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播&#xff0c;愿成为中国 “隐私计算最后一公里的服务区”。183篇原创内容公众号…

全网最全虚拟机的封装

1.服务器初始化 系统环境RHEL7.6 2.禁用selinux [rootserver1 ~]# vim /etc/sysconfig/selinux SELINUXdisabled reboot 3.禁用防火墙 [rootserver1 ~]# systemctl disable --now firewalld 4.配置yum源 [rootserver1 ~]# vim /etc/fstab /dev/mapper/rhel…

AC的改进算法——TRPO、PPO

两类AC的改进算法 整理了动手学强化学习的学习内容 1. TRPO 算法&#xff08;Trust Region Policy Optimization&#xff09; 1.1. 前沿 策略梯度算法即沿着梯度方向迭代更新策略参数 。但是这种算法有一个明显的缺点&#xff1a;当策略网络沿着策略梯度更新参数&#xff0c…

(考研湖科大教书匠计算机网络)第五章传输层-第五节:TCP拥塞控制

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;拥塞控制概述二&#xff1a;拥塞控制四大算法&#xff08;1&#xff09;慢开始和拥塞避免A&#xff1a;慢启动&#xff08;slow start&#xff09;…

CTFer成长之路之举足轻重的信息搜集

举足轻重的信息搜集CTF 信息搜集 常见的搜集 题目描述: 一共3部分flag docker-compose.yml version: 3.2services:web:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-information-backk:latestports:- 80:80启动方式 docker-compose up -d 题目Flag n1book{in…

设计模式-代理模式

控制和管理访问 玩过扮白脸&#xff0c;扮黑脸的游戏吗&#xff1f;你是一个白脸&#xff0c;提供很好且很友善的服务&#xff0c;但是你不希望每个人都叫你做事&#xff0c;所以找了黑脸控制对你的访问。这就是代理要做的&#xff1a;控制和管理对象。 监视器编码 需求&…

数据挖掘,计算机网络、操作系统刷题笔记49

数据挖掘&#xff0c;计算机网络、操作系统刷题笔记49 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;orac…

Spring Cloud Alibaba 微服务简介

微服务简介 1 什么是微服务 2014年&#xff0c;Martin Fowler&#xff08;马丁福勒 &#xff09; 提出了微服务的概念&#xff0c;定义了微服务是由以单一应用程序构成的小服务&#xff0c;自己拥有自己的进程与轻量化处理&#xff0c;服务依业务功能设计&#xff0c;以全自动…

将Nginx 核心知识点扒了个底朝天(四)

为什么 Nginx 不使用多线程&#xff1f; Apache: 创建多个进程或线程&#xff0c;而每个进程或线程都会为其分配 cpu 和内存&#xff08;线程要比进程小的多&#xff0c;所以 worker 支持比 perfork 高的并发&#xff09;&#xff0c;并发过大会榨干服务器资源。 Nginx: 采用…

程序员35岁中年危机不是坎,是一把程序员自己设计的自旋锁

有时候&#xff0c;我会思考35岁这个程序员的诅咒&#xff0c;确切来说是中国程序员的独有的诅咒。 优秀的程序员思维逻辑严谨&#xff0c;弄清楚需求的本质是每天重复的工作&#xff0c;也是对工作的态度&#xff0c;那弄清楚诅咒的来源&#xff0c;义不容辞。 被诅咒的35岁 …

【爬虫】自动获取showdoc指定项目中的所有文档

▒ 目录 ▒&#x1f6eb; 导读需求1️⃣ 格式分析官方下载文件内容prefix_info.json文件格式2️⃣ 封包分析/api/page/info/api/item/info3️⃣ 编码代码特点问题&#x1f4d6; 参考资料&#x1f6eb; 导读 需求 showdoc是一个API文档、技术文档工具网站&#xff0c;经常能搜到…

String intern方法理解

1、原理 参考学习视频&#xff1a; https://www.bilibili.com/video/BV1WK4y1M77t/?spm_id_from333.337.search-card.all.click&vd_source4dc3f886f5ce1d43363b603935f02bd1 String s1 “hello”; String s1 "hello"; 代码原理解释如下图String s1 new Str…

进程章节总结性实验

进程实验课笔记 本节需要有linux基础&#xff0c;懂基本的linux命令操作即可。 Ubuntu镜像下载 https://note.youdao.com/s/VxvU3eVC ubuntu安装 https://www.bilibili.com/video/BV1j44y1S7c2/?spm_id_from333.999.0.0 实验环境ubuntu22版本&#xff0c;那个linux环境都可以…

Linux-VMware常用设置(时间+网络)及网络连接激活失败解决方法-基础篇②

目录一、设置时间二、网络设置1. 激活网卡方法一&#xff1a;直接启动网卡&#xff08;仅限当此&#xff09;方法二&#xff1a;修改配置文件&#xff08;永久&#xff09;2. 将NAT模式改为桥接模式什么是是NAT模式&#xff1f;如何改为桥接模式&#xff1f;三、虚拟机网络连接…

20230219 质心和重心的区别和性质

质心&#xff1a;&#xff08;无需重力场的前提&#xff09;所有质点的位置关于它们的质量的加权平均数。 重心&#xff1a;&#xff08;需要重力场的前提&#xff09;重力对系统中每个质点关于重心的力矩之和为零。 质心&#xff1a; xˉ∑i1nmixi∑i1nmi,yˉ∑i1nmiyi∑i1nmi…

Fiddler的报文分析

目录 1.Statistics请求性能数据 2.检测器&#xff08;Inspectors&#xff09; 3.自定义响应&#xff08;AutoResponder&#xff09; 1.Statistics请求性能数据 报文分析&#xff1a; Request Count: 1 请求数&#xff0c;该session总共发的请求数 Bytes …

vue3.0 生命周期

目录前言&#xff1a;vue3.0生命周期图例1.beforeCreate2.created3.beforeMount/onBeforeMount4.mounted/onMounted5.beforeUpdate/onBeforeUpdate6.updated/onUpdated7.beforeUnmount/onBeforeUnmount8.unmounted/onUnmounted案例&#xff1a;总结前言&#xff1a; 每个Vue组…

智慧城市应急指挥中心数字化及城市驾驶舱建设方案

目 录 第一章 项目概述 1.1 项目背景 1.2 项目范围 第二章 建设内容 2.1 三维可视化平台 2.1.1 多源数据接入 2.1.2 可视化编排 2.1.3 三维可视化编辑 2.1.4 空间数据可视化 2.1.5 集成框架支持 2.2 可视化场景定制开发 2.2.1 城市驾驶总舱 2.2.2 城市安全分舱 2.…