解题报告Best Time to Buy and Sell Stock with Cooldown
题目
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 as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]
解题思路:
第一种方案, 假设数组长度为n, dp[i][j]为从i到j所能达到的最大收益,那么本题即求dp[0][n - 1],
对于dp[i][j], 其可能的cooldown位置有 I, i + 1, ..., j - 1, j,
所以存在递推关系
dp[i][j] = max{ dp[i][k - 1] + dp[k + 1][j]} k = i, i + 1, ... , j - 1, j
当k == i 时, dp[i][k - 1] 不存在,即只有dp[k + 1][j], 同理
当k == j 时, dp[k + 1][j] 不存在,即只有dp[i][k - 1]
prices[j] - prices[I] 为dp[I][j]的初始值
所以最终dp[i][j] = max(prices[j] - prices[I], max{dp[i][k - 1] + dp[k + 1][j]})
而题目希望求解的是dp[0][n - 1]. 所以i 从n-1往0求解,j从0往n-1求解
时间复杂度O(n^3) 空间复杂度O(n^2)
代码如下
class Solution {
public:
//suppose cooldown at k
//dp[i][j] = max{dp[i][k - 1] + dp[k + 1][j]} k = i ... j
int maxProfit(vector<int>& prices) {
int n = prices.size();
if (0 == n) return 0;
vector<vector<int>> dp(n, vector<int>(n, 0));
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
dp[i][j] = prices[j] - prices[i];
}
}
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
//cout<<"i="<<i<<" j="<<j<<" "<<dp[i][j]<<endl;
for (int k = i; k < j; k++) {
int tmp = 0;
if (k - 1 >= i) {
tmp += dp[i][k - 1];
}
if (k + 1 <= j) {
tmp += dp[k + 1][j];
}
dp[i][j] = max(dp[i][j], tmp);
}
}
}
return dp[0][n - 1];
}
};
第二种方案:顺序DP
常规的DP的类型主要有三类,矩阵dp,一个一维数组的dp,两个一维数组的dp
矩阵dp 构造f[i][j], 一维dp构造f[i], 两个一维dp构造f[i][j]
本题恰好可以使用顺序dp,而且是一维的数组
解题思路:
每一天股票的持有状态可能有三种情况
cool down-->buy-->sell-->cool down-->buy-->sell-->cool down
状态转换的关系如上, leetcode讨论区有人画了状态图,非常容易理解, 参考链接
https://leetcode.com/explore/interview/card/top-interview-questions-hard/121/dynamic-programming/862/discuss/75928/Share-my-DP-solution-(By-State-Machine-Thinking)
也就是说
buy的状态 可能是从前一个buy 或者前一个cool down过来
sell的状态 只能是从前一个buy过来
cool down的状态 可能是从前一个cool down或者前一个sell的状态过来
这里需要搞清楚
1)sell 和 cool down的区别, sell状态只有 卖出的那个时刻状态是保持的, 卖完第二天状态就是cool down了.
2)buy 到 sell 之间的这段时间,按题意并不算cool down,而全是buy状态
3)sell 到 cool down之间的这段时间,全是cool down状态
由此可以得出
buy[i] = max(buy[i - 1], rest[i - 1] - prices[I]) // 这里用rest 表示 cool down
rest[i] = max(rest[i - 1], sell[I - 1])
sell[I] = buy[I - 1] + prices[i]
代码如下
java
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
if (0 == n) return 0;
int[] buy = new int[n];
int[] rest = new int[n];
int[] sell = new int[n];
buy[0] = -prices[0];
rest[0] = 0;
sell[0] = Integer.MIN_VALUE;
for (int i = 1; i < n; i++) {
buy[i] = Math.max(buy[i - 1], rest[i - 1] - prices[i]);
rest[i] = Math.max(rest[i - 1], sell[i - 1]);
sell[i] = buy[i - 1] + prices[i];
}
return Math.max(rest[n - 1], sell[n - 1]);
}
}
c++
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if (0 == n) return 0;
vector<int> buy(n, 0);
vector<int> rest(n, 0);
vector<int> sell(n, 0);
buy[0] = -prices[0];
rest[0] = 0;
//不可能存在,所以收益取最小,因为i位置,我们希望取的是最大值,
//将sell设置为最小值,表示永远不可能取该值
sell[0] = INT_MIN;
for (int i = 1; i < n; i++) {
buy[i] = max(buy[i - 1], rest[i - 1] - prices[i]);
rest[i] = max(rest[i - 1], sell[i - 1]);
sell[i] = buy[i - 1] + prices[i];
}
return max(rest[n - 1], sell[n - 1]);
}
};
解题报告Best Time to Buy and Sell Stock with Cooldown的更多相关文章
- LeetCode解题报告—— Best Time to Buy and Sell Stock
Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...
- leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown
121. Best Time to Buy and Sell Stock 题目的要求是只买卖一次,买的价格越低,卖的价格越高,肯定收益就越大 遍历整个数组,维护一个当前位置之前最低的买入价格,然后每次 ...
- Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown)
Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown) 股票问题: 121. 买卖股票 ...
- 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...
- [LeetCode] Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- [LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- Best Time to Buy and Sell Stock with Cooldown
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- LeetCode Best Time to Buy and Sell Stock with Cooldown
原题链接在这里:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 题目: Say you hav ...
- 121. 122. 123. 188. Best Time to Buy and Sell Stock *HARD* 309. Best Time to Buy and Sell Stock with Cooldown -- 买卖股票
121. Say you have an array for which the ith element is the price of a given stock on day i. If you ...
随机推荐
- 什么是spark(一) 分区以及和MR的区别
什么是spark,是一个分布式计算平台,或者说是分布式计算引擎,他的职责就是将指定的数据读入到各个node的内存中,然后计算.所以spark是具有泛化性质的,只要数据源是可读入的,读到内存里面之后,处 ...
- MEF学习总结(2)---Primitive层
Primitive层是属于依赖注入的通用模型,主要有如下核心类型: 1. ComposablePart是核心类,他表示组件容器中的每一个组件,是对真正组件实例的包装.ExportDefinition属 ...
- Python——str常用操作方法
1. 索引(即下标) s = 'ABCDEFGHIJKLMN' s1 = s[0] print('s[0] = ' + s1) #s[0] = A print('s[3] = '+ s[3]) #s[ ...
- RK3288 添加USB转虚拟串口设备
在系统开启并有日志打印的前提下,插入USB设备,就会打印USB设备和虚拟串口信息. 打印信息如下: 供应商ID(VID):idVendor=1234,产品ID(PID): idProduct=5678 ...
- Unit05: 实战技巧 、 资费列表 、 拦截器
Unit05: 过滤器解决表单写中文乱码.拦截器 1. 使用过滤器解决表单中文参数值乱码问题 注意: a. 表单提交方式必须为POST. b. 过滤器的编码应该与浏览器端设置的编码一致. 2. 拦截器 ...
- qt在动态库里面加载widget的例子
testDll和testExe项目 备注:windows下dll内不需要new QApplication, linux和mac下面需要在动态库里面new QApplication testdll.h ...
- 历届试题 小数第n位(小技巧)
问题描述 我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数. 如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式. 本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始 ...
- windows10 vs2015编译 带nginx-rtmp-module 模块的32位nginx
1 下载必要软件 从 http://xhmikosr.1f0.de/tools/msys/下载msys:http://xhmikosr.1f0.de/tools/msys/MSYS_MinGW-w6 ...
- Jetty实战(杂七杂八)
最近开始选择JETTY作为服务器了,乘这现在空闲点学习了些JETTY的部署知识,原来她真的跟TOMCAT很类似,先总结如下: 部署应用方法(下载好jetty); 方法一: 直接将应用的 war包放在j ...
- Linux更换jdk版本的一些问题
111111111111111111111111111111111111111111111111111111111111111111111111 在服务器上更新了新的 jdk,也在 /etc/prof ...