解题报告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 ...
随机推荐
- (转)Maven的pom.xml文件结构之Build配置build
在Maven的pom.xml文件中,Build相关配置包含两个部分,一个是<build>,另一个是<reporting>,这里我们只介绍<build>. 1. 在M ...
- Tomcat(64位)免安装版的环境安装与配置
本篇博客主要介绍Tomcat(64位)免安装版的环境安装与配置,该篇文章同样适合于32位Tomcat免安装版的环境安装与配置. 该篇博客中的大部分内容同百度经验中的<出现unable to op ...
- SharePoint无法搜索解决
重启服务器后,站点搜索时提示错误,无法进行搜索,进入管理中心搜索管理看到,"查询处理"出错. 解决方法: 停止搜索服务,重新启动,如下图所示 重启服务后,过了几分钟重新查询,查询正 ...
- Markdown初步使用
一.兼容 HTML Markdown 的理念是,能让文档更容易读.写和随意改.HTML 是一种发布的格式,Markdown 是一种书写的格式.就这样,Markdown 的格式语法只涵盖纯文本可以涵盖的 ...
- Linux命令-chmod、chown和chgrp
Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而禁 ...
- SpringMVC+Spring+Mybatis -- 集成之旅
准备 首先介绍一下,我的工具使用的是STS, 需要的童鞋可以到官网下载:http://spring.io/tools/sts/all 使用STS是因为她集成了Maven进行 “包“ 管理以及自带 We ...
- Servlet文件上传和下载的复习
上传 使用Servlet完成上传和下载相较于使用Struts框架有点麻烦,毕竟更偏底层了 项目中主要使用的jar包: commons-io-2.2.jar commons-fileupload-1. ...
- 【UVa】208 Firetruck(dfs)
题目 题目 分析 一开始不信lrj的话,没判联通,果然T了. 没必要全部跑一遍判,只需要判断一下有没有点与n联通,邻接表不太好判,但无向图可以转换成去判n与什么联通. 关于为什么要判,还是因为 ...
- 浅谈PHP面向对象编程(一、简介)
传统的面向过程 将要完成的工作,分作若干个步骤,或再细分为子步骤,然后后步骤从前往后一步一步完成,最初达致目标. 现代的面向对象 将要完成的工作拆分为“一个一个对象”的任务(功能),每个对象独自完成自 ...
- java 字符串排序
http://bbs.csdn.net/topics/280032929 大可不需要那样复杂了!(一)如果要排序的为字符串,如:String sortStr = "ACDFE"; ...