当前位置: 首页 > news >正文

Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV买卖股票的最佳时机III

Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III&&309.买卖股票的最佳时机含冷冻期

动态规划应该如何学习?-CSDN博客

本次题解参考自灵神的做法,大家也多多支持灵神的题解

买卖股票的最佳时机【基础算法精讲 21】_哔哩哔哩_bilibili

希望读者在阅读之前先看完这篇博客

Day43 | 动态规划 :状态机DP 买卖股票的最佳时机&&买卖股票的最佳时机II-CSDN博客

动态规划学习:

1.思考回溯法(深度优先遍历)怎么写

注意要画树形结构图

2.转成记忆化搜索

看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算

3.把记忆化搜索翻译成动态规划

基本就是1:1转换

文章目录

  • Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III&&309.买卖股票的最佳时机含冷冻期
    • 188.买卖股票的最佳时机IV
      • 思路分析(子问题):
      • 1.回溯 DFS
      • 2.记忆化搜索
      • 3.1:1翻译为动态规划
      • 4.滚动数组优化
    • 123.买卖股票的最佳时机III

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

188. 买卖股票的最佳时机 IV - 力扣(LeetCode)

思路分析(子问题):

状态机的变化:多了一个参数j表示我们最多可以交易几笔

image-20241113171715687

在加减prices[i]的时候进行j-1,表示我们进行了一笔交易,那剩下在递归的时候最多只能交易j-1次

注意:j-1只在加prices[i]或者减prices[i]的时候写一次,加表示我们卖出,可以看做一次交易,减表示一次买进,也可以看做一次交易,但是加减prices[i]的时候都写,就说明我们买进一次再卖出算成了两次交易,这样就错了

image-20241113172010082

笔者觉得在卖出的时候进行交易次数的计算比较好,就使用这个

递归边界部分,和前两道题不同的就是j如果小于0了那肯定就是不合法的状态,因为我们的交易次数最少应该是0,所以就返回一个负无穷表示这是不合法的

1.回溯 DFS

1.返回值和参数

i是每天的价格

status是状态,表示是否持有股票

j是我们现在最多可以交易多少笔

dfs返回值是我们在前i天持有或者不持有股票,在最多交易j次的前提下可以获得的最大利润

int dfs(int i,int j,int status,vector<int>& prices)

2.终止条件

就是在前两题的基础上了一个不合法的状态,那就是交易次数小于0的话要返回负无穷

注意判断的顺序,交易次数j一定要先判断,因为只要j小于0那肯定是不合法的

		if(j<0)return INT_MIN;if(i<0)if(status==1) return INT_MIN;elsereturn 0;

3.本层逻辑

在我们加prices[i]的时候,就说明是卖出股票,就说明第i天进行了一次交易,第i天的利润是prices[i],那前i-1天的利润就是在最多交易j-1笔的情况下的最大利润,传入j-1

		if(status==1)return max(dfs(i-1,j,1,prices),dfs(i-1,j,0,prices)-prices[i]);elsereturn max(dfs(i-1,j,0,prices),dfs(i-1,j-1,1,prices)+prices[i]);

完整代码:

当然,这是超时的

class Solution {
public:int dfs(int i,int j,int status,vector<int>& prices){if(j<0)return INT_MIN;if(i<0)if(status==1) return INT_MIN;elsereturn 0;if(status==1)return max(dfs(i-1,j,1,prices),dfs(i-1,j,0,prices)-prices[i]);elsereturn max(dfs(i-1,j,0,prices),dfs(i-1,j-1,1,prices)+prices[i]);}int maxProfit(int k,vector<int>& prices) {return dfs(prices.size()-1,k,0,prices);}
}; 

2.记忆化搜索

就是搞一个哈希表dp,全都初始化为-1,每次返回前给哈希表dp赋值,碰到不是-1的那就是算过的,那就直接返回计算过的结果,不需要再次递归了

class Solution {
public:int dfs(int i,int j,int status,vector<int>& prices,vector<vector<vector<int>>>& dp){if(j<0)return INT_MIN;if(i<0)if(status==1) return INT_MIN;elsereturn 0;if(dp[i][j][status]!=-1)return dp[i][j][status];if(status==1)return dp[i][j][status]=max(dfs(i-1,j,1,prices,dp),dfs(i-1,j,0,prices,dp)-prices[i]);elsereturn dp[i][j][status]=max(dfs(i-1,j,0,prices,dp),dfs(i-1,j-1,1,prices,dp)+prices[i]);}int maxProfit(int k,vector<int>& prices) {vector<vector<vector<int>>> dp(prices.size(),vector<vector<int>>(k+1,vector<int>(2,-1)));return dfs(prices.size()-1,k,0,prices,dp);}
}; 
//lambda
class Solution {
public:int maxProfit(int k,vector<int>& prices) {vector<vector<vector<int>>> dp(prices.size(),vector<vector<int>>(k+1,vector<int>(2,-1)));function<int(int,int,int)> dfs=[&](int i,int j,int status)->int{if(j<0)return INT_MIN;if(i<0)if(status==1) return INT_MIN;elsereturn 0;if(dp[i][j][status]!=-1)return dp[i][j][status];if(status==1)return dp[i][j][status]=max(dfs(i-1,j,1),dfs(i-1,j,0)-prices[i]);elsereturn dp[i][j][status]=max(dfs(i-1,j,0),dfs(i-1,j-1,1)+prices[i]);};return dfs(prices.size()-1,k,0);}
}; 

3.1:1翻译为动态规划

1.确定dp数组以及下标的含义

image-20241113173659276

dfs换成dp就是数组以及下标含义

2.确定递推公式

dp[i+1][j][0]=max(dp[i][j][0],dp[i][j-1][1]+prices[i]);
dp[i+1][j][1]=max(dp[i][j][1],dp[i][j][0]-prices[i]);

3.dp数组如何初始化(难理解的点)

1.第一维度prices.size()+1是我们的数组下标表示天数的i从1开始

2.表示交易次数的j初始化是k+2的大小是因为

-1,0,1,2,…,k一共是k+2个状态,这一点和递归里面的对应

3.对应递归的终止条件,j必须大于0才是合法的,其他的都是不合法的,所以一开始初始化都是负无穷(除以2是为了防止溢出)

然后单独把j大于0,并且是第0天(对应i<0的if),也不持有股票(对应的是递归里的if(status==0))都赋值为0,表示这种情况下没有利润

vector<vector<vector<int>>> dp(prices.size()+1,vector<vector<int>>(k+2,vector<int>(2,INT_MIN/2)));
for(int i=1;i<=k+1;i++)dp[0][i][0]=0;

4.确定遍历顺序

后续结果需要依赖前面的计算结果,故使用从前往后遍历

		for(int i=0;i<prices.size();i++){for(int j=1;j<=k+1;j++){dp[i+1][j][0]=max(dp[i][j][0],dp[i][j-1][1]+prices[i]);dp[i+1][j][1]=max(dp[i][j][1],dp[i][j][0]-prices[i]);}}

完整代码

class Solution {
public:int maxProfit(int k,vector<int>& prices) {vector<vector<vector<int>>> dp(prices.size()+1,vector<vector<int>>(k+2,vector<int>(2,INT_MIN/2)));for(int i=1;i<=k+1;i++)dp[0][i][0]=0;for(int i=0;i<prices.size();i++){for(int j=1;j<=k+1;j++){dp[i+1][j][0]=max(dp[i][j][0],dp[i][j-1][1]+prices[i]);dp[i+1][j][1]=max(dp[i][j][1],dp[i][j][0]-prices[i]);}}return dp[prices.size()][k+1][0];}
}; 

4.滚动数组优化

和01背包一样,前面都是i后面都是i-1

由于j要靠j-1推出来,所以需要从后往前遍历j

class Solution {
public:int maxProfit(int k,vector<int>& prices) {vector<vector<int>> dp(k+2,vector<int>(2,INT_MIN/2));for(int i=1;i<=k+1;i++)dp[i][0]=0;for(int i=0;i<prices.size();i++){for(int j=k+1;j>=1;j--){dp[j][0]=max(dp[j][0],dp[j-1][1]+prices[i]);dp[j][1]=max(dp[j][1],dp[j][0]-prices[i]);}}return dp[k+1][0];}
}; 

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

[123. 买卖股票的最佳时机 III - 力扣(LeetCode)](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/)

就是上一题k=2的情况,带进去就完了,直接结束

相关文章:

Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV买卖股票的最佳时机III

Day44 | 动态规划 &#xff1a;状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III&&309.买卖股票的最佳时机含冷冻期 动态规划应该如何学习&#xff1f;-CSDN博客 本次题解参考自灵神的做法&#xff0c;大家也多多支持灵神的题解 买卖股票的最佳时机【…...

Area-Composition模型部署指南

一、介绍 本模型可以通过输入不同的提示词&#xff0c;然后根据各部分提示词进行融合生成图片。如下图&#xff1a; 此图像包含 4 个不同的区域&#xff1a;夜晚、傍晚、白天、早晨 二、部署 环境要求&#xff1a; 最低显存&#xff1a;10G 1. 部署ComfyUI 本篇的模型部署…...

策略模式、状态机详细解读

策略模式 (Strategy Pattern) 策略模式 (Strategy Pattern) 是一种行为型设计模式&#xff0c;旨在将一组算法封装成独立的类&#xff0c;使得它们可以相互替换。这种模式让算法的变化不会影响到使用算法的客户&#xff0c;减少了类之间的耦合。策略模式通常用于处理一类问题&…...

OpenWrt广播DNS到客户端

OpenWrt广播DNS到客户端 Network -> Interfaces -> lan ->DHCP Server -> Advanced Settings -> DHCP-Options 设置 6,dns1,dns2 如下图 也可以直接编辑 /etc/config/dhcp config dhcp lan list dhcp_option 6,119.29.29.29,223.5.5.5 #ipv4 option dns 2402:4…...

C++编程技巧与规范-类和对象

类和对象 1. 静态对象的探讨与全局对象的构造顺序 静态对象的探讨 类中的静态成员变量(类类型静态成员) 类中静态变量的声明与定义&#xff08;类中声明类外定义&#xff09; #include<iostream> using namespace std;namespace _nmspl {class A{public:A():m_i(5){…...

AutoHotKey自动热键AHK-正则表达式

在这个软件的操作中,基本都是需要即时的解决一些问题,所以对字符串的操作是比较多的,所以正则的使用还是比较重要的,接下来我们用一个例子来了解正则表达式的使用 str "7654321" RegExMatch(str, "65(43)(21)", SubPat)str ( str %str% SubPat %SubPa…...

【3D Slicer】的小白入门使用指南四

开源解剖影像浏览工具Open Anatomy Browser使用及介绍 和3D slicer米有太大关系,该工具是网页版影像数据的浏览工具(可以简单理解为网页版的3D slicer) 介绍 ● 开放解剖(OA)浏览器是由神经影像分析中心开发的,基于网络浏览器技术构建的图谱查看器。 ● OA浏览器将解剖模…...

flink同步mysql数据表到pg库

1.关闭防火墙和selinux systemctl stop firewalld systemctl disable firewalld systemctl status firewalldvi /etc/selinux/config 修改为disabled2.安装java8 yum list java-1.8* yum install java-1.8.0-openjdk* -yjava -version3.下载和部署postgresql 下载地址&#…...

AndroidStudio-常用布局

一、线性布局LinearLayout 线性布局内部的各视图有两种排列方式: 1.orientation属性值为horizontal时&#xff0c;内部视图在水平方向从左往右排列。 2.orientation属性值为vertical时&#xff0c;内部视图在垂直方向从上往下排列。 如果不指定orientation属性&#xff0c;…...

Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发 1.设计公共响应数据类型 文件地址&#xff1a;utils/response404.py from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code 400def __init__(self, err_list, *args, **kwargs):data {"error_c…...

[Android]查找java类中声明为native方法的具体实现方法

在android代码中&#xff0c;经常可以看到native方法&#xff0c;需要查看其对应的C方法&#xff0c;这些方法是一一对应的&#xff0c;对应关系是在jni注册里关联起来的。 比较直观的是这样的例子&#xff0c; Parcel.java //Java层的方法里调用了native方法nativeWriteInt…...

Exploring Defeasible Reasoning in Large Language Models: A Chain-of-Thought A

文章目录 题目摘要简介准备工作数据集生成方法实验结论 题目 探索大型语言模型中的可废止推理&#xff1a;思路链 论文地址&#xff1a;http://collegepublications.co.uk/downloads/LNGAI00004.pdf#page136 摘要 许多大型语言模型 (LLM) 经过大量高质量数据语料库的训练&…...

uniapp在app模式下组件传值

在 UniApp 编译成 App 后&#xff0c;传递参数可以通过多种方式实现&#xff0c;常见的方式有以下几种&#xff1a; 1. 通过 URL 参数传递&#xff08;适用于 WebView&#xff09; 如果你的 App 页面通过 WebView 渲染&#xff0c;可以像在 Web 端一样通过 URL 传递参数。例如…...

Docker解决暴露2375端口引发的安全漏洞

docker的暴露api端口2375&#xff0c;没有任何安全防护&#xff0c;我们通过linux系统防火墙&#xff08;iptables&#xff09;来进行ip访问限制 # 查看iptables所有规则 iptables -L -nv # 只允许某个ip访问2375端口 iptables -I INPUT -s 127.0.0.1 -p tcp --dport 2375 -j A…...

HTML5+CSS前端开发【保姆级教学】+新闻文章初体验

Hello&#xff0c;各位编程猿们&#xff01;上一篇文章介绍了前端以及软件的安装&#xff0c;这一篇我们要继续讲解页面更多知识点&#xff0c;教大家做一篇新闻题材的文章 新闻文章 当我们点开浏览器经常看到各种各样的文章&#xff0c;今天我们就来看看大家最喜欢关注的体育…...

『VUE』26. props实现子组件传递数据给父组件(详细图文注释)

目录 本节内容示例代码总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 本节内容 父组件传子组件–props 子组件传父组件–自定义事件 本节讲子组件传父组件–通过props里的方法传递,就是父亲写了一个函数,给子组件调用,然后…...

RHCE-DNS域名解析服务器

一、DNS简介 DNS &#xff08; Domain Name System &#xff09;是互联网上的一项服务&#xff0c;它作为将域名和 IP 地址相互映射的一个分布式 数据库&#xff0c;能够使人更方便的访问互联网。 DNS 系统使用的是网络的查询&#xff0c;那么自然需要有监听的 port 。 DNS 使…...

移民统计年鉴(1996-2021年)

年鉴中包含了以下几个方面的数据&#xff1a; 移民数量&#xff1a;记录了每年全球移民的总数&#xff0c;以及不同国家和地区的移民流入和流出情况。 移民类型&#xff1a;区分了经济移民、难民、家庭团聚等不同类型的移民。 移民原因&#xff1a;分析了推动移民的各种因素&…...

MFC1(note)

引言 在学习SDK后我们发现&#xff0c;写消息好麻烦&#xff0c;处理消息更麻烦 处理消息效率低发送消息效率低 所以把SDK中这些消息全部封装好 MFC封装了windows 的大部分API 这里说一下QT架构跨平台 MFC用得如何取决于你SDK的水平 创建 如果打开没有MFC 一般勾选以下…...

1.1 关于游戏编程

1.1.1、游戏中客户端和服务器的交互 游戏通常采用客户端-服务器模式‌。在这种模式下&#xff0c;服务器负责处理游戏的核心逻辑、数据存储和玩家间的交互&#xff0c;而客户端则负责呈现游戏画面、接收玩家输入并与服务器通信‌。 客户端和服务器的作用和功能 ‌客户端‌&a…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...