Leetcode(W9):188. Best Time to Buy and Sell Stock IV(动态规划)
来源:互联网 发布:互联网java 技术路线 编辑:程序博客网 时间:2024/05/16 03:40
leetcode中Best Time to Buy and Sell Stock买卖股票的最佳时间总共有5道类型题。
参考这位大牛的博客:传送门
1. Best Time to Buy and Sell Stock IV
介绍:
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
题意:
给定一个数组,下标代表第几天,元素值即为当天可买进或卖出的股票价格,现在设定我们最多能进行K次交易(注意每次卖都必须卖光,不能说我今天1块钱买入明天2块钱卖出,后天又能3块钱卖出,一次交易只能一次买对应一次卖),谋取最大利益然后输出这个最大利益。
思路:
我们之前用动态规划,是不是就觉得这种题目应该存在通解的呢,通解能方便计算当题目条件为“能进行K次交易”时的情景。如果我们能把通解即最多能进行K次交易解决了。
定一个数组global[i][j]为第一天到第i天可以最多进行j次交易的最好的利润,再定一个数组local[i][j]为第一天到第i天可以最多进行j次交易且最后一次卖出必须发生在第i天这天的最好的利润。
那么推出今天的全局最优只需要比较两种情况,要么是刚好今天卖出去赚了的局部最优,要么今天卖出去会亏,所以就仍是昨天的全局最优,视这两者谁大而定,所以全局数组递推式为
global[i][j]=max(local[i][j],global[i-1][j])
而今天的局部最优则限定了最后一次交易必须在今天卖出,仍然要比较两种情况:
一、昨天进行j-1次交易的全局最优,加上最后一次交易在今天卖出所得的利润diff,关于diff也有两种情况:
①、如果最后一次交易今天卖出但又不是今天买进的,即最后一次交易利润大于0,那么diff就是prices[i + 1] - prices[i];
②、如果条件①里不存在利润大于0的情况,比如股票一直下跌,那么最后一次交易只能是今天买今天卖,此时diff为0
所以diff直接取①和②中的最大值即可
二、最后一次交易发生在昨天的局部最优,然后我们把昨天的“卖出”调到今天,并且不管赚还是亏都得今天卖出,所以不需要像上面那样比较,局部最优直接加上差价prices[i + 1] - prices[i]即可,所以diff仍然是prices[i + 1] - prices[i]。
最后,今天的局部最优取一和二中的最大值即可。
局部数组的递推式为
local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff)
发现没有,因为每一天都存在全局最优和局部最优两条路走,所以每次递推都是在跟昨天的全局最优和局部最优作比较,然后贪心地选择最优的那个。
注意:这道题有一种特殊情况是跟Best Time to Buy and Sell Stock II一模一样的,如果k的值大于等于prices的天数,此时你是可以做到第一天买,然后接下来只要一出现利润就卖出去的操作的(因为从第二天开始每一天你都能卖出再买进),这道题也就跟II一模一样了。所以应该采取II里的解法,II的思路传送门在此。
操作:
local[k]表示进行k次交易的局部最优
global[k]表示进行k次交易的全局最优,我们要求的值即为global[k]
i从第一天遍历到最后一天,j从k遍历到1
由于先更新local,所以global可以直接 max(global[j], local[j]);这里第一个参数global[j]正好还是昨天的,而第二个参数local[j]正好是今天的。
而对于local,local中global[j-1]和local[j]刚好也是昨天(i-1的时候)算出来的,所以都不用二维数组global[i-1][j-1],local[i-1][j]来计算那么麻烦了,因为取昨天的值再覆盖掉就行了。
用一维数组来代替二维数组,可以极大的节省了空间,由于覆盖的顺序关系,我们需要j从2到1,这样可以取到正确的g[j-1]值,而非已经被覆盖过的值
2. 代码
int solveMaxProfit(vector<int>& prices) { int profit = 0; for (int i = 1; i < prices.size(); i++) { if (prices[i] - prices[i-1] > 0) { profit += prices[i] - prices[i-1]; } } return profit;}int maxProfit(int k, vector<int>& prices) { if (prices.size() == 0) { return 0; } if (prices.size() <= k) {//当Best Time to Buy and Sell Stock II来做 return solveMaxProfit(prices); } int local[k+1] = {0}; int global[k+1] = {0}; for (int i = 0; i < prices.size()-1; i++) { int diff = prices[i+1] - prices[i]; for (int j = k; j >= 1; j--) { local[j] = max(global[j-1] + max(diff, 0), local[j]+diff); global[j] = max(global[j], local[j]); } } return global[k];}
- Leetcode(W9):188. Best Time to Buy and Sell Stock IV(动态规划)
- Leetcode(W9):123. Best Time to Buy and Sell Stock III(动态规划)
- 【LeetCode】Best Time to Buy and Sell Stock IV 动态规划dp解法(C++)
- 【动态规划】Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV(动态规划)
- LeetCode 188 Best Time to Buy and Sell Stock IV (动态规划 推荐)
- [leetcode] 188.Best Time to Buy and Sell Stock IV
- [leetcode] 188.Best Time to Buy and Sell Stock IV
- [leetcode] 188. Best Time to Buy and Sell Stock IV
- [LeetCode] 188. Best Time to Buy and Sell Stock IV
- Leetcode 188. Best Time to Buy and Sell Stock IV
- 【leetcode】188. Best Time to Buy and Sell Stock IV
- LeetCode 188. Best Time to Buy and Sell Stock IV
- Leetcode 188. Best Time to Buy and Sell Stock IV
- Leetcode 188. Best Time to Buy and Sell Stock IV
- Leetcode 188. Best Time to Buy and Sell Stock IV
- LeetCode 188. Best Time to Buy and Sell Stock IV
- 动态规划-188. Best Time to Buy and Sell Stock IV
- 使用Scrapy框架爬取腾讯招聘信息
- C++时钟类 模拟电子时钟 设置时间后可自动更新时间
- JAVA基础复习二十一-IO流-字符流
- Andrew Ng's deeplearning Course1Week4 Deep neural network(深层神经网络)
- python3实现爬取淘宝页面的商品的数据信息(selenium+pyquery+mongodb)
- Leetcode(W9):188. Best Time to Buy and Sell Stock IV(动态规划)
- LeetCode #712 Minimum ASCII Delete Sum for Two Strings
- 10531053. Path of Equal Weight (30)
- 机器学习(2)-梯度下降
- 学习笔记TF062:TensorFlow线性代数编译框架XLA
- 四周五次课(11月10日)10.4 logging 10.5 os模块 10.6 command模块 10.7 sys模块
- Material Design控件之FloatingActionButton
- 测试者出的APP测试面试题
- UVa 10222 Decode the Mad man