题目

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的更多相关文章

  1. 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 ...

  2. 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 题目的要求是只买卖一次,买的价格越低,卖的价格越高,肯定收益就越大 遍历整个数组,维护一个当前位置之前最低的买入价格,然后每次 ...

  3. 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. 买卖股票 ...

  4. 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  5. [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 ...

  6. [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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. js前台调用lodop打印

    lodop简单介绍 lodop的打印功能已经非常强大,也在带web端的图形界面,可以供用户使用.使用js在前台调用lodop打印,一般分为两种方法: 1:特殊的指令打印,这种打印方式,是采用的与js无 ...

  2. Linux VPS上DenyHosts阻止SSH暴力攻击

    2009年07月23日 下午 | 作者:VPS侦探 现在的互联网非常不安全,很多人没事就拿一些扫描机扫描ssh端口,然后试图连接ssh端口进行暴力破解(穷举扫描),所以建议vps主机的空间,尽量设置复 ...

  3. 优化html标签

    借用Effective之名,开始写Effective系列,总结一些前端的心得. 有些人写页面会走向一个极端,几乎页面所有的标签都用div,究其原因,用div有很多好处,一个是div没有默认样式,不会有 ...

  4. 搭建基于hyperledger fabric的联盟社区(四) --chaincode开发

    前几章已经分别把三台虚拟机环境和配置文件准备好了,在启动fabric网络之前我们要准备好写好的chaincode.chaincode的开发一般是使用GO或者JAVA,而我选择的是GO语言.先分析一下官 ...

  5. 阿里云SLB快速切换至https

    域名caifuxiang.com是直接解析到阿里云SLB的,运行了好几年的http服务,今天通过修改配置快速切换到了https,莫名就感觉更上档次了! 首先,SSL证书 服务可以提供免费单域名证书 w ...

  6. Spring AOP两种实现方式

    一. AOP 概念: Spring AOP 即Aspect Oriented Programming(面向切面编程), 实现方式分为两种: 1. 注解(Annotation) 2. 配置(Config ...

  7. Java字符代码中干掉制表符、回车符和换行符

    Java字符代码中干掉制表符.回车符和换行符 代码片段: String sql = StringUtils.trim(sql).replaceAll("[\\r\\n\\t]",& ...

  8. Spring的常用下载地址

    第一种,简单粗暴直接 1 http://repo.springsource.org/libs-release-local/org/springframework/spring/3.2.4.RELEAS ...

  9. Apache common exec包的相应使用总结

      最近在写一个Java工具,其中调用了各种SHELL命令,使用了Runtime.getRuntime().exec(command);这个方法.但是在我调用某个命令执行操作时,程序就卡在那了,但是其 ...

  10. canvas之画矩形

    <canvas id="canvas" width="600" height="500" style="background ...