day42-买卖股票3-k次买卖+冷冻期+手续费

### 9.28 188. Best Time to Buy and Sell Stock IV
You are given an integer array prices where prices`[i] is the price of a given stock on the ith day, and an integer k.
Find the maximum profit you can achieve. You may complete at most k transactions: i.e. you may buy at most k times and sell at most k times.
Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/description/
 188.买卖股票的最佳时机IV  
本题是123.买卖股票的最佳时机III 的进阶版  
https://www.bilibili.com/video/BV16M411U7XJ
https://programmercarl.com/0188.%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%BAIV.html

dp`[i][2k]:第k次不持有

```java
for(j = 0; j < 2k, j += 2){
    //第i天第j次持有股票最大获利: 新买入/之前就有
    //第i天买入股票了:dp[i-1][j] - price[i]
    //第i天没有操作,沿用前一天买入股票的状态:dp[i-1][j+1]
    dp[i][j+1] = Math.max( (dp[i-1][j]-price[i]), dp[i-1][j+1] );
    //第i天第j次不持有股票最大获利: 卖掉了/之前就不要了
    //第i天卖出股票了:dp[i-1][j+1] + price[i] 
    //第i天没有操作,沿用前一天卖出股票的状态:dp[i-1][j+2]
    dp[i][j+2] = Math.max( (dp[i-1][j+1]+price[i]), dp[i-1][j+2] );
}

//初始化:
dp[0][0] = 0;//未操作
dp[0][1] = -price[0];//买入
dp[0][2] = 0;//卖出
//...
//所以dp数组初始化:
for(int i = 1; i < 2k; i += 2){
    dp[0][i] = -price[i];
}
```

```java
public class stock188 {  
    public int maxProfit(int k, int[] prices) {  
        int[][] dp = new int[prices.length][2 * k + 1];  
        for (int i = 1; i < 2 * k; i += 2) {  
            dp[0][i] = -prices[0];  
        }  
        for (int i = 1; i < prices.length; i++) {  
            for (int j = 0; j < 2 * k; j += 2) {  
                //hold  
                dp[i][j + 1] = Math.max((dp[i - 1][j + 1]), (dp[i - 1][j] - prices[i]));  
                //unhold  
                dp[i][j + 2] = Math.max((dp[i - 1][j + 2]), (dp[i - 1][j + 1] + prices[i]));  
            }  
        }  
//        for (int i = 0; i < dp.length; i++) {  
//            for (int j = 0; j < dp[i].length; j++) {  
//                System.out.print("dp["+i+"]["+j+"] = " + dp[i][j] + " ");  
//            }  
//            System.out.println();  
//        }  
        return dp[prices.length - 1][2 * k];  
    }  
}  
  
class stock188Test {  
    public static void main(String[] args) {  
        stock188 example = new stock188();  
        int[] prices = {3,2,6,5,0,3};  
        int k = 2;  
        System.out.println(example.maxProfit(k,prices));  
    }  
  
}
```

### 9.29 309. Best Time to Buy and Sell Stock with Cooldown
You are given an array prices where prices[i] is the price of a given stock on the ith day.
Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times) with the following restrictions:
After you sell your stock, you cannot buy stock on the next day (i.e., cooldown one day).
Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
309.最佳买卖股票时机含冷冻期 
本题加了一个冷冻期,状态就多了,有点难度,大家要把各个状态分清,思路才能清晰 
https://www.bilibili.com/video/BV1rP4y1D7ku
https://programmercarl.com/0309.%E6%9C%80%E4%BD%B3%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E6%97%B6%E6%9C%BA%E5%90%AB%E5%86%B7%E5%86%BB%E6%9C%9F.html  

dp`[i][0]:未操作
dp`[i][1]:持有股票(继续持有/才买的)
dp`[i][2]:不持有股票(继续不持有/刚卖的)
持有股票:
继续持有,重新买
不持有股票:
继续不持有,刚卖

自己写碰到的问题:不知道怎么判断什么时候卖了股票

dp`[i][0]:持有股票(1.继续持有;2.前一天是冷冻期,第i天买了股票;3.前一天处于保持卖出股票的状态,第i天新买了股票)
dp`[i][1]:保持卖出股票的状态(1.延续前一天;2.前一天是冷冻期)
dp`[i][2]:第i天卖出了股票
dp`[i][3]:冷冻期(冷冻期的前一天一定是卖出股票的状态)

本题初始化的问题:dp`[i][1]是非法状态,初始化值要根据递推公式需要的值来确定。

```java
public class stock309 {  
    public int maxProfit(int[] prices) {  
        int l = prices.length;  
        int[][] dp = new int[l][4];  
        dp[0][0] = -prices[0];  
        dp[0][1] = 0;  
        dp[0][2] = 0;  
        dp[0][3] = 0;  
  
        for (int i = 1; i < l; i++) {  
            //dp`[i][0]:持有股票(1.继续持有;2.前一天是冷冻期,第i天买了股票;3.前一天处于保持卖出股票的状态,第i天新买了股票)  
            //dp`[i][1]:保持卖出股票的状态(1.延续前一天;2.前一天是冷冻期)  
            //dp`[i][2]:第i天卖出了股票  
            //dp`[i][3]:冷冻期(冷冻期的前一天一定是卖出股票的状态)  
            dp[i][0] = Math.max(Math.max((dp[i-1][0]),dp[i-1][3] - prices[i]),dp[i-1][1]-prices[i]);  
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][3]);  
            dp[i][2] = dp[i-1][0] + prices[i];  
            dp[i][3] = dp[i-1][2];  
        }  
        int max = 0;  
        for (int i = 0; i < dp[l -1].length; i++) {  
            if(dp[l -1][i] > max){  
                max = dp[l -1][i];  
            }  
        }  
        return max;  
    }  
}  
class stock309Test {  
    public static void main(String[] args) {  
        stock309 example = new stock309();  
        int[] prices = {1};  
        System.out.println(example.maxProfit(prices));  
    }  
}
```
### 9.30 714. Best Time to Buy and Sell Stock with Transaction Fee
You are given an array prices where prices`[i] is the price of a given stock on the ith day, and an integer fee representing a transaction fee.
Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction.
Note:
You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
The transaction fee is only charged once for each stock purchase and sale.
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/
 714.买卖股票的最佳时机含手续费  
相对122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的,可以尝试自己做一做。
https://www.bilibili.com/video/BV1z44y1Z7UR
https://programmercarl.com/0714.%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%E5%90%AB%E6%89%8B%E7%BB%AD%E8%B4%B9%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html

 股票总结 

股票问题做一个总结吧
https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92-%E8%82%A1%E7%A5%A8%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93%E7%AF%87.html  

dp`[i][0]:第i天持有股票得到的最大利润
dp`[i][1]:第i天不持有股票得到的最大利润

```java
public class stock714 {  
    public int maxProfit(int[] prices, int fee) {  
        int[][] dp = new int[prices.length][2];  
        dp[0][0] = -prices[0];  
  
        for (int i = 1; i < prices.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] - fee);  
        }  
  
        return Math.max(dp[prices.length-1][0],dp[prices.length-1][1]);  
  
    }  
}  
class stock714Test {  
    public static void main(String[] args) {  
        stock714 example = new stock714();  
        int[] prices = {1,3,2,8,4,9};  
        int fee = 2;  
        System.out.println(example.maxProfit(prices,fee));  
    }  
}
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值