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

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

返回获得利润的最大值。

示例 1:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:

  • 0 < prices.length <= 50000.
  • 0 < prices[i] < 50000.
  • 0 <= fee < 50000.

一、思路

(一)贪心算法

思路很简单,从后往前遍历数组,遇到高价则将其设置为出售价格,每次出售股票时,计算当前利润与上一次利润之和,再计算一下此次交易若以上一次的售价出售,所能得到的利润,对比两者的大小,选择利润高的方式出售。

C++代码:

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {// 初始化售价、购买价、上一次出售价、如果以上一次售价出售所能得到的利润int sale=prices[prices.size()-1], pre_sale=0, pur=0, fit;// 总利润、当前这次交易的利润、上一次交易的利润int profit=0, cur_profit=0, pre_profit=0;for(int i=prices.size()-2; i >= 0; i--){if(prices[i] > sale){sale = prices[i];continue;}// 准备买卖pur = prices[i];cur_profit = sale - pur - fee;fit = pre_sale - pur - fee;if(fit > 0 && fit >= max(pre_profit + cur_profit, pre_profit)){profit = profit - pre_profit + fit;pre_profit = fit;sale = pur;continue;}if(cur_profit > 0){profit += cur_profit;pre_profit = cur_profit;pre_sale = sale;sale = pur;}}return profit;}
};

(二)动态规划

1、状态转移框架


建立动态规划表dp[i][j]dp[i][j]dp[i][j]:

  • i:表示第i天
  • j:表示当前股票的持有状态,0表示没有持有股票,1表示持有股票

动态规划表dp[i][j]dp[i][j]dp[i][j]的意义就很明显了,就在第i天时,手里持有股票(j=1)或者没有持股(j=0)所能获取的最大利润。

除此之外,在这一天,还有3种操作可选:buy、sell、rest。

我们现在要做的就是遍历所有可能的状态,求出利润最大的,那么这里的解题伪代码可以写成:

for 0 <= i < n:for j in {0, 1}:dp[i][j] = max{buy, sell, rest}

于是所求的答案为:dp[n−1][0]dp[n - 1][0]dp[n−1][0]

4、状态转移方程

  • dp[i][0]=max(dp[i−1][0],dp[i−1][1]+prices[i]−fee)dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee)dp[i][0]=max(dp[i−1][0],dp[i−1][1]+prices[i]−fee)
    这个方程表达的意思是:在第i天,手里没有持股,所能获取的最大利润为dp[i][0]dp[i][0]dp[i][0]
    那么这个利润是怎么来的?这要从当前的状态分析,因为当前没有持股,要么昨天没有持股,要么昨天持股,但是今天卖掉了,这里卖掉需要减去一个手续费才是最终的利润。
  • dp[i][1]=max(dp[i−1][1],dp[i−1][0]−prices[i])dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])dp[i][1]=max(dp[i−1][1],dp[i−1][0]−prices[i])
    这个方程表达的意思是:在第i天,手里持股,所能获取的最大利润为dp[i][1]dp[i][1]dp[i][1]
    那么这个利润是怎么来的?这要从当前的状态分析,因为当前持股,要么昨天持股,要么昨天没有持股,但是今天买入了股票。

C++代码:

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {if(prices.size() == 0 || prices.size() == 1)return 0;vector<vector<int>> dp(prices.size(), vector<int>(2, 0));// 初始化dp[0][1] = -prices[0];dp[1][0] = max(dp[0][0], dp[0][1] + prices[1] - fee);dp[1][1] = max(dp[0][1], dp[0][0] - prices[1]);// 状态转移for(int i=2; i < prices.size(); 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]);}return dp[prices.size() - 1][0];}
};

leetcode714-买卖股票的最佳时机含手续费相关推荐

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

    1.题目描述: 给定一个整数数组prices,其中prices[i]表示第i天的股票价格:整数fee代表了交易股票的手续费用.你可以无限次地完成交易,但是你每笔交易都需要付手续费.如果你已经购买了一个 ...

  2. leetcode714. 买卖股票的最佳时机含手续费(动态规划)

    给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 :非负整数 fee 代表了交易股票的手续费用. 你可以无限次地完成交易,但是你每笔交易都需要付手续费.如果你已经购买了一个 ...

  3. leetcode714.买卖股票的最佳时机含手续费(中等)

    思路:贪心. 手续费和买股票的价格放在一起考虑,第一次付了手续费,相当于下次就能免费买股票了,并且prices[i]为买的费用. 代码细节:遍历,如果比自己当前付出的钱 多,则卖出并且免手续费买了这支 ...

  4. 2022-3-4 Leetcode714.买卖股票的最佳时机含手续费

    贪心算法 class Solution {public:int maxProfit(vector<int>& prices, int fee) {int n = prices.si ...

  5. 代码随想录算法训练营第三十七天 | 738.单调递增的数字,714. 买卖股票的最佳时机含手续费,968.监控二叉树,总结

    Day36 周日休息~ 一.参考资料 单调递增的数字 https://programmercarl.com/0738.%E5%8D%95%E8%B0%83%E9%80%92%E5%A2%9E%E7%9 ...

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

    该题目和以下题目相关联,感兴趣的小伙伴可直接点击下面的链接! LeetCode121:买卖股票的最佳时机 LeetCode122:买卖股票的最佳时机 II LeetCode123:买卖股票的最佳时机 ...

  7. 【LeetCode】买卖股票的最佳时机含手续费 [M](动态规划)

    714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode) 一.题目 给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 :整数 fee 代表了交易股票的手续费用 ...

  8. 714. 买卖股票的最佳时机含手续费(CPP)

    714. 买卖股票的最佳时机含手续费 给定一个整数数组 pricespricesprices,其中第 iii 个元素代表了第 iii 天的股票价格 :非负整数 feefeefee 代表了交易股票的手续 ...

  9. LeetCode 714 买卖股票的最佳时机含手续费

    714. 买卖股票的最佳时机含手续费 题目 思路 过一遍,记录第i天是否买入和卖出的最值. 代码 class Solution {public:int maxProfit(vector<int& ...

  10. 【算法】贪心算法:LeetCode 714 买卖股票的最佳时机含手续费 、LeetCode 968 监控二叉树

    LeetCode 714 买卖股票的最佳时机含手续费 (中等) 题目 描述 给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 :整数 fee 代表了交易股票的手续费用. 你 ...

最新文章

  1. Jquery真的不难~第八回 JS的闭包问题
  2. ncnn tensorrt
  3. 教你认清MVC,MVP和MVVM
  4. 为什么ABAP里有些场景必须加上COMMIT WORK才生效
  5. Swift - 循环强引用,内存泄漏
  6. 检测系列--YOLO系列
  7. 【PyTorch 】静态图与动态图机制
  8. 在线留痕阅卷系统功能说明及其演示
  9. HTML5网页设计——新闻页面制作
  10. 【电力电子】【2019.12】工业用三相全SIC PWM整流器
  11. 美版iphone更新系统无服务器,iPhone 升级系统提示无法检查更新如何解决?
  12. 无法启动程序,.dll不是有效的Win32应用程序
  13. 23种设计模式-多例模式《柒个我》
  14. 6种纯css3徽章样式
  15. 如何在 Debian、Ubuntu 以及其它 Linux 发行版上安装 ONLYOFFICE 桌面编辑器 v7.2 版本
  16. 读javascript高级程序设计02-变量作用域
  17. el-input-number 默认值设置失效
  18. 源中的 backports proposed security updates 什么意思?
  19. 智能时代 算力赋能 | 有孚云·智算上线-聚智云算,向新而生!
  20. 传世服务器上怎么修改升级经验,传世各级升级需要的经验

热门文章

  1. 【中途结题】基于弥亚微Mi200E的模块通信实验
  2. 计算机网络 学习通 第三章作业
  3. APK获取包名的办法
  4. python 导入的nan怎么解决_如何在Python中使用Lmfit解决NaN值错误
  5. 【XSY3657】因数分解(容斥,DP)
  6. 重置计算机网络配置后上不了网,路由器重置后上不了网怎么办 怎么重新设置路由器...
  7. android 跳转oppo应用中心_Android 遍历手机应用,跳转应用市场详情页面
  8. 等一台聪明的炒菜机器人 炒热风口上的智能家居
  9. opengl编程基础篇
  10. 移动硬盘加密后在linux中如何使用方法,移动硬盘加密的方法你都知道吗?