详细布置
股票问题是一个动态规划的系列问题,今日安排的题目不多,大家可以慢慢消化。
视频讲解:https://www.bilibili.com/video/BV1Xe4y1u77q
https://programmercarl.com/0121.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA.html
感觉股票问题不简单
这道题一眼就可以暴力算,但是怎么dp呢。
如果dp数组含义是: 第i天卖出的最大价值dp[i] ,感觉也是很暴力算法啊。
直接看题解吧
太有难度啦
dp[i][0] 表示第i天持有股票所得最多现金 ,dp[i][1] 表示第i天不持有股票所得最多现金
注意这里说的是“持有”,“持有”不代表就是当天“买入”!也有可能是昨天就买入了,今天保持持有的状态
如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);
如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来
同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
这样递推公式我们就分析完了
因为每一天都是 买或不买 和 卖或不卖。
如果已经买了,就不可能再买,就要保持原状;还没买就可以买入。这两种选一个最大的
如果已经卖了,就不可能再卖,就要保持原状;还没卖就可以卖掉。这两种选一个最大的。
第一天不持有是0,持有是 -price
就是正序遍历
对于 i 天持有的情况,比较的是 i - 1 持有的价格和 -price
而不是 i - 1 不持有 - price。
因为只买卖一次,一开始净收入 0 ,第一次买入就是 -price
股票问题感觉就是状态很多
class Solution {
public int maxProfit(int[] prices) {
//dp[i][0] 第i天不持有
//dp[i][1] 第i天持有
int[][] dp = new int[prices.length][2];
//初始化
dp[0][0] = 0;
dp[0][1] = -prices[0];
//递推公式
for (int i = 1; i < dp.length; i++) {
//这一天不持有的话
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
//这一天持有的话
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
}
return dp[dp.length - 1][0];
}
}
视频讲解:https://www.bilibili.com/video/BV1D24y1Q7Ls
https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html
直接看题解,这道题是可以反复买卖这只股票。
其实就是我做股票1的时候写错的那部分哈哈哈
无
无
class Solution {
public int maxProfit(int[] prices) {
//dp[i][0] 第i天不持有
//dp[i][1] 第i天持有
int[][] dp = new int[prices.length][2];
//初始化
dp[0][0] = 0;
dp[0][1] = -prices[0];
//递推公式
for (int i = 1; i < dp.length; i++) {
//这一天不持有的话
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
//这一天持有的话
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[dp.length - 1][0];
}
}