一、题目描述
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入: prices = [1,2,3,0,2] 输出: 3 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
二、解题思路
看到求最优值,想到用动态规划,但该题的动态规划转移方程稍微有些复杂,因为每个时间点的状态有3个,分别如下:
有股票:
(1)手上有一支股票f[i][0](要么是当天买入,要么是前一天买入而今天没有操作)
没有股票:
(2)手上不持有股票,处于冷冻期f[i][1](因为卖出股票,所以i天结束后处于冷冻期)
(3)手上不持有股票,且不处于冷冻期 f[i][2](当天没有进行任何操作,且i天结束后不处于冷冻期(也就是说手上不持有股票是由于没有操作导致而不是当天卖出股票导致),此处的冷冻期表示当天结束之后处于冷冻期)
以上三种情况,f[i][j]表示目前的累计最大收益
因为计算某一天股票最大收益是必须计算当天过完时股票的最终收益的,所以必须计算股票在当天的变化
三、代码实现
//注意该题中在每个时间点dp存在多种状态,所以必须考虑(利用dp[i][0]、dp[i][1]...表示)
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
if(len==0){
return 0;
}
//设计状态变量
int[][] dp=new int[len][3];
//初始值
dp[0][0]=-prices[0];
dp[0][1]=0;
dp[0][2]=0;
for (int i = 1; i < len; i++) {
//第i天有股票
dp[i][0]=Math.max(dp[i-1][2]+prices[i],dp[i-1][0]);
//第i天没有股票,且卖出(i+1天处于冷冻期)
dp[i][1]=dp[i-1][0]+prices[i];
//第i天没有进行任何操作,且没有股票(i+1天不处于冷冻期)
dp[i][2]=Math.max(dp[i-1][1],dp[i-1][2]);
}
return Math.max(dp[len-1][1],dp[len-1][2]);
}
}
最完该题后的最大收获就是:动态规划中,若某点的状态有多个,可以用二维数组表示改点的各个状态,然后根据改点与前一点各个状态的关系构造状态转移方程