【错题集-编程题】买卖股票的最好时机(四)(动态规划)

力扣对应题目链接:188. 买卖股票的最佳时机 IV - 力扣(LeetCode)

牛客对应题目链接:买卖股票的最好时机(四)_牛客题霸_牛客网 (nowcoder.com)


一、分析题目

1、状态表示

为了更加清晰的区分买入卖出,我们换成有股票无股票两个状态。

  • f[i][j] 表示:第 i 天结束后,完成了 j 笔交易,此时处于有股票状态的最大收益。
  • g[i][j] 表示:第 i 天结束后,完成了 j 笔交易,此时处于无股票状态的最大收益。

2、状态转移方程

对于 f[i][j],也有两种情况能在第 i 天结束之后,完成 j 笔交易,此时手里有股票的状态:

  • i-1 天的时候,手里有股票,并且交易了 j 次。在第 i 天的时候,啥也不干。此时的收益为 f[i - 1][j]
  • i-1 天的时候,手里没有股票,并且交易了 j 次。在第 i 天的时候,买了股票。那么 i 天结束之后,就有股票了。此时的收益为 g[i - 1][j] - prices[i]

上述两种情况,我们需要的是最大值,因此 f 的状态转移方程为:

f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]

对于 g[i][j],我们有下⾯两种情况能在第 i 天结束之后,完成 j 笔交易,此时手里没有股票的状态:

  • i-1 天的时候,手里没有股票,并且交易了 j 次。在第 i 天的时候,啥也不干。此时的收益为 g[i - 1][j]
  • i-1 天的时候,手里有股票,并且交易了 j - 1 次。在第 i 天的时候,把股票卖了。那么 i 天结束之后,我们就交易了 j 次。此时的收益为 f[i - 1][j - 1] + prices[i]

上述两种情况,我们需要的是最大值,因此 g 的状态转移方程为:

g[i][j] = max(g[i - 1][j], f[i - 1][j - 1] + prices[i])

它们之间交易关系如下:


3、初始化

由于需要用到 i=0 时的状态,因此我们初始化第一行即可。
  • 当处于第 0 天的时候,只能处于买入过⼀次的状态,此时的收益为 -prices[0] ,因f[0][0] = - prices[0]
  • 为了取 max 的时候,⼀些不存在的状态起不到干扰的作⽤,我们统统将它们初始化为 -INF(用 INT_MIN 在计算过程中会有溢出的风险,这⾥ INF 折半取 0x3f3f3f3f ,足够小即可)。

4、填表顺序

从上往下填每一行,每一行从左往右,两个表⼀起填。

5、返回值

返回处于卖出状态的最大值,但是我们也不知道是交易了几次,因此返回 g 表最后一行的最大值。


6、优化

我们的交易次数是不会超过整个天数的一半的,因此我们可以先把 k 处理一下,优化一下问题的规模:k = min(k, n / 2)


二、代码

//力扣
//【动态规划-二维dp-2个状态】
class Solution {//f[i][j]:第i天结束后,完成了j次交易,此时处于“买入”状态下的最大利润//g[i][j]:第i天结束后,完成了j次交易,此时处于“卖出”状态下的最大利润
private:const int INF=0x3f3f3f3f;
public:int maxProfit(int k, vector<int>& prices) {int n=prices.size();k=min(k, n/2); //优化:处理最多交易次数vector<vector<int>> f(n, vector<int>(k+1, -INF));vector<vector<int>> g(n, vector<int>(k+1, -INF));f[0][0]=-prices[0], g[0][0]=0;for(int i=1; i<n; i++){for(int j=0; j<=k; j++){f[i][j]=max(f[i-1][j], g[i-1][j]-prices[i]);g[i][j]=g[i-1][j];if(j>=1) g[i][j]=max(g[i][j], f[i-1][j-1]+prices[i]);}}int res=0;for(int j=0; j<=k; j++)res=max(res, g[n-1][j]);return res;}
};//【动态规划-二维dp-2k+1个状态】
class Solution {//dp[i][0] -- 没有操作//下面j为奇数:买入;j为偶数:卖出 (j的范围:1~2k-1)//dp[i][j] -- 第1~k次买入//dp[i][j+1] -- 第1~k次卖出
public:int maxProfit(int k, vector<int>& prices) {int n=prices.size();vector<vector<int>> dp(n, vector<int>(2*k+1));for(int j=1; j<2*k; j+=2)dp[0][j]=-prices[0];for(int i=1; i<n; i++){for(int j=0; j<2*k; j+=2){dp[i][j+1]=max(dp[i-1][j+1], dp[i-1][j]-prices[i]);dp[i][j+2]=max(dp[i-1][j+2], dp[i-1][j+1]+prices[i]);}}return dp[n-1][2*k];}
};
//牛客
#include <iostream>
#include <cstring>
using namespace std;const int INF=0x3f3f3f3f;
const int N=1010, M=110;
int prices[N];
int f[N][M], g[N][M];
//f[i][j]:第i天结束后,完成了j次交易,此时处于“买入”状态下的最大利润
//g[i][j]:第i天结束后,完成了j次交易,此时处于“卖出”状态下的最大利润int main()
{int n, k;cin >> n >> k;for(int i=0; i<n; i++)cin >> prices[i];memset(f, -INF, sizeof(f));memset(g, -INF, sizeof(g));int res=0;f[0][0]=-prices[0], g[0][0]=0;for(int i=1; i<n; i++){for(int j=0; j<=k; j++){f[i][j]=max(f[i-1][j], g[i-1][j]-prices[i]);g[i][j]=g[i-1][j];if(j>0) g[i][j]=max(g[i][j], f[i-1][j-1]+prices[i]);res=max(res, g[i][j]);}}cout << res << endl;return 0;
}//值得学习的代码
#include <iostream>
using namespace std;const int N = 1010, M = 110;int n, k, p[N];
int f[N][M], g[N][M];int main()
{cin >> n >> k;for(int i = 0; i < n; i++) cin >> p[i];k = min(k, n / 2);for(int j = 0; j <= k; j++) f[0][j] = g[0][j] = -0x3f3f3f3f;f[0][0] = -p[0], g[0][0] = 0;for(int i = 1; i < n; i++){for(int j = 0; j <= k; j++){f[i][j] = max(f[i - 1][j], g[i - 1][j] - p[i]);g[i][j] = g[i - 1][j];if(j >= 1) g[i][j] = max(g[i][j], f[i - 1][j - 1] + p[i]);}}int ret = 0;for(int j = 0; j <= k; j++) ret = max(ret, g[n - 1][j]);cout << ret << endl;return 0;
}

三、反思与改进

买卖股票这种类似有系列的题目,需要把核心知识点彻底弄熟。

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

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

相关文章

【鸿蒙学习笔记】通过用户首选项实现数据持久化

官方文档&#xff1a;通过用户首选项实现数据持久化 目录标题 使用场景第1步&#xff1a;源码第2步&#xff1a;启动模拟器第3步&#xff1a;启动entry第6步&#xff1a;操作样例2 使用场景 Preferences会将该数据缓存在内存中&#xff0c;当用户读取的时候&#xff0c;能够快…

云WAF | 云waf基础知识详解

随着数字时代的到来&#xff0c;网络安全问题越来越突出&#xff0c; Web应用防火墙&#xff08;WAF&#xff09;是保障 Web应用安全的一道重要防线。在云计算环境下&#xff0c;云环路由云平台&#xff08;WAF&#xff09;的出现&#xff0c;其融合了 WAF的能力和云计算的灵活…

【Linux】IP地址与主机名

文章目录 1.IP地址2.特殊IP地址3.主机名4.域名解析 1.IP地址 每一台联网的电脑都会有一个地址&#xff0c;用于和其它计算机进行通讯 IP地址主要有2个版本&#xff0c;V4版本和V6版本 IPv4版本的地址格式是&#xff1a;a.b.c.d,其中abcd表示0~255的数字&#xff0c;如192.168.…

PS 2024【最新】中文白嫖版!,安装教程,图文步骤

文章目录 软件介绍软件下载安装步骤 软件介绍 Photoshop&#xff0c;简称“PS” Adobe Photoshop&#xff0c;简称“PS”&#xff0c;是由Adobe Systems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具&#xff0c;可以有效地…

探索Facebook在人工智能领域的最新进展

在当今快速发展的科技领域中&#xff0c;人工智能&#xff08;AI&#xff09;作为一项关键技术&#xff0c;正在逐步改变着社交媒体的面貌。作为全球最大的社交平台之一&#xff0c;Facebook积极探索和应用人工智能&#xff0c;以提升用户体验、增强平台安全性并推动技术创新。…

Nodejs 第八十四章(ElasticSearch搜索)

ElasticSearch基本用法在之前的篇章介绍过了 这里不在过多阐述 模拟假数据 安装库 faker-js/faker 模拟假数据的一个库非常好用支持中文使用中文 locale: [zh_CN], 设置即可生成名字&#xff0c;邮箱&#xff0c;手机号&#xff0c;id&#xff0c;年龄&#xff0c;性别生成完成…

ATT 和 GATT:数据表示和交换

背景介绍 BLE的通信和以太网&#xff0c;wifi有个重大的不同是&#xff1a;BLE通信的设备往往有特定的功能。且这个功能不会在运行中发生变化。 因此蓝牙设备通信的时候&#xff0c;只能访问预先定义好的&#xff08;也就是配置文件profile&#xff09;的功能。 那profile里写…

批量制作word表格

问题背景 将excel表中的成绩内容制作为成绩单&#xff0c;每页对应一个学员的成绩&#xff0c;方便打印 代码实现 ## 导入包 import pandas as pd from docx import Document from docx.enum.text import WD_ALIGN_PARAGRAPH,WD_LINE_SPACING# 读取 Excel 内容 df pd.read_e…

IP 地址:优化网络游戏

IP地址和网络游戏 在现代网络游戏中&#xff0c;IP地址不仅用于服务器分配&#xff0c;还能针对性进行玩家匹配与优化网络延迟。本文将探讨IP地址在网络游戏中的具体应用。 *服务器分配* 全球服务器分布&#xff1a; 网络游戏需要在全球范围内提供快速、稳定的连接&#xff…

libcoap3对接华为云平台

文章目录 前言一、平台注册二、引入源码库1.libcoap仓库编译2.分析网络报文3.案例代码4.编译&运行 总结 前言 通过libcoap3开源代码库对接华为云平台&#xff0c;本文章将讨论加密与不加密的方式对接华为云平台。 一、平台注册 首先&#xff0c;你需要在华为云平台上创建…

文华财经盘立方博易大师boll布林带指标公式源码

TT:TIME>850&&TIME<1150; MID:MA(CLOSE,26);//求N个周期的收盘价均线&#xff0c;称为布林通道中轨 TMP2:STD(CLOSE,26);//求M个周期内的收盘价的标准差 TOP:MID2*TMP2;//布林通道上轨 BOTTOM:MID-2*TMP2;//布林通道下轨 A:EVERY(ISDOWN,2)&&TT&&…

【鸿蒙学习笔记】使用axios进行HTTP数据请求

官方文档&#xff1a;网络管理开发概述 目录标题 访问淘宝公开接口&#xff08;测试数据&#xff09;第1步&#xff1a;module.json5 配置网络授权第2步&#xff1a;下载axios第3步&#xff1a;源码第4步&#xff1a;启动模拟器第5步&#xff1a;启动entry第6步&#xff1a;操…

论文AI痕迹过重怎么办?AI降痕工具来帮忙

如何有效利用AI工具提高工作效率&#xff1f;探索这5款顶级AI写作工具 不知道大家有没有发现&#xff0c;随着人工智能技术的快速发展&#xff0c;AI工具正逐渐渗透到我们日常生活的各个方面&#xff0c;极大地提高了我们的工作和学习效率。无论是AI写作、AI绘画、AI思维导图&…

排序(一)——冒泡排序、直接插入排序、希尔排序(BubbleSOrt,InsertSort,ShellSort)

欢迎来到繁星的CSDN&#xff0c;本期的内容主要包括冒泡排序(BubbleSort&#xff09;&#xff0c;直接插入排序(InsertSort)&#xff0c;以及插入排序进阶版希尔排序&#xff08;ShellSort&#xff09;。 废话不多说&#xff0c;直接上正题&#xff01; 一、冒泡排序 冒泡排序…

制作微信商城的步骤是什么

在当今这个数字化时代&#xff0c;微信已成为人们日常生活中不可或缺的一部分。随着微信生态的日益完善&#xff0c;微信商城成为了众多企业和商家拓展线上业务、触达潜在客户的重要渠道。那么&#xff0c;如何制作一个高效、专业的微信商城呢&#xff1f;本文将为您详细解析制…

做突破交易时,需要注意的进场细节有哪些?

突破交易揭示了市场未来的走向。 在这种情况下&#xff0c;面对市场时我们应该如何入场操作呢&#xff1f;接下来&#xff0c;让我们来细化一下实施的具体步骤。 01. 在交易中&#xff0c;周期的考量比价格突破更为关键。 当价格突破发生时&#xff0c;市场的平静被打破&#x…

生物素化的曼陀罗凝集素;Datura Stramonium Lectin

一、基本信息 中文名称&#xff1a;生物素化的曼陀罗凝集素 英文名称&#xff1a;Datura Stramonium Lectin (Biotinylated) 常用名&#xff1a;曼陀罗凝集素&#xff0c;生物素化 CAS号&#xff1a;N/A&#xff08;因不同制造商和产品而异&#xff0c;且可能未公开&#xff09…

MySQL黑马教学对应视屏笔记分享之聚合函数,以及排序语句的讲解笔记

聚合函数 注意&#xff1a;null值不参与聚合函数的计算。 分组查询 2.where与having的区别 执行时机不同&#xff1a;where是在分组之前进行过滤&#xff0c;不满足where条件&#xff0c;不参与分组&#xff1b;而having是分组之后对结果进行过滤。判断条件不同&#xff1a;w…

【区块链 + 智慧政务】一体化政务数据底座平台 | FISCO BCOS应用案例

为进一步贯彻落实《全国一体化政务大数据体系建设方案》、《中共中央国务院关于构建数据基础制度更好发挥 数据要素作用的意见》精神&#xff0c;一体化政务数据底座平台结合相应城市的数字经济现状基础、当前任务及未来发展 战略&#xff0c;规划建设数据底座&#xff0c;持续…

新品牌快速成长指南:揭秘品牌成功的黄金法则

打造一个新品牌是一个系统性工程&#xff0c;不是一两句话就能说清楚的。 作为一个13年的营销人&#xff0c;今天试图给大家以最简练和通俗的文字&#xff0c;详细讲讲打造一个全新的品牌都需要做些啥&#xff1f;码字不易&#xff0c;请多给点支持哦。 一、市场调研与定位&a…