动态规划 06

124 阅读2分钟

LeetCode 309

原题链接

解题思路

运用动态规划算法

设一个二维数组dp,其值就是最大收益
第一维度是天数,第二维度是3种情况的状态。

分析状态如下:

0.当天持有股票,且今天不是冷冻期
1.当天不持有股票,且今天是冷冻期
2.当天不持有股票,且今天不是冷冻期(观望)

Note:还有一种情况是 当天持有股票,且今天是冷冻期。这与题意矛盾。
今天是冷冻期,说明前一天卖了股票,今天是不会持有股票的。所以共3中情况。

状态转移分析:

0:现在有股票。 (1)今天的股票是昨天已经持有的。dp[i-1][0];
(2)今天持有的股票是今天买的。dp[i-1][2] - prices[i];
今天买的股票前一天就不能有,说明前一天是观望状态。

1: 没股票,冷冻期 今天是冷冻期,且没有股票,说明前一天把股票卖了
只有一种情况:dp[i-1][0]+prices[i] 即:前一天有股票的情况0,再加上当天股票价格,
因为dp是最大收益,前面已经把成本扣除了,直接加利润就行。

2:没股票,非冷冻期。
说明在前一天之前已经经历过卖出和冷冻了,什么事都不做,现在观望何时买入股票。
所以前一天是不持有股票的,对应了前一天的状态0和1。 dp[i-1][1]dp[i-1][2]

初始化

dp[0][0] = -prices[0] 第一天持有股票,说明第一天一上来就买股票

dp[0][1] = 0 本来第一天不会出现冷冻期情况,但是由上分析1状态是由前一天0状态决定。

dp[0][2] = 0 第一天就开始观望

代码如下

public class test {

    public int maxProfit(int[] prices) {
    	if(prices.length == 0) {
    		return 0;
    	}
    	int n = prices.length;
    	/*
    	 * dp值为最大收益
    	 * 第一维是天数,对应第二维的3中状态
    	 * 状态0:当天持有股票,并不处于冷冻期
    	 * 状态1:当天没有股票,并处于冷冻期
    	 * 状态2:当天没有股票,并不处于冷冻期
    	 */
    	int[][] dp = new int[n][3];
    	dp[0][0] = -prices[0];
    	dp[0][1] = 0;
    	dp[0][2] = 0;
    	for (int i = 1; i < n; i++) {
    		dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2] - prices[i]);
    		dp[i][1] = dp[i-1][0] + prices[i];
    		dp[i][2] = Math.max(dp[i-1][1], dp[i-1][2]);
		}
    	return Math.max(dp[n-1][1], dp[n-1][2]);
    }

	public static void main(String[] args) {
		int[] prices = {1,2,3,0,2};
		test t = new test();
		System.out.println(t.maxProfit(prices));
	}

}