五.接上一篇 leetcode 123:你最多可以完成 两笔 交易

dp1数组存储第`i`天,持有股票的最大利润
dp2数组存储第`i`天,不持有股票的最大利润

增加一个维度,交易次数, 0-还有两次交易机会 1-表示还有一次交易机会

dp1[0][i] = Math.max(dp1[0][i-1], -a[i]);//还有两次交易机会:前一天就持股,今天不操作;前一天没有持股,今天买
dp1[1][i] = Math.max(dp1[1][i-1], dp2[0][i-1]-a[i]);//还有一次交易机会:前一天就持股,今天不操作;前一天没有持股,今天买
dp2[0][i] = Math.max(dp2[0][i-1], a[i] + dp1[0][i-1]);//还有两次交易机会:前一天就没有持股,今天不操作;前一天持股,今天卖
dp2[1][i] = Math.max(dp2[1][i-1], a[i] + dp1[1][i-1]);//还有一次交易机会:前一天就没有持股,今天不操作;前一天有持股,今天卖

注:之前在四就说过了,可以把dp1和dp2合并成一个二维数组,如果合并成二维数组,本题就变成三维数组了,代码部分

 1 public static int maxProfit(int[] a) {
 2         if (a.length == 0 || a.length == 1) {
 3             return 0;
 4         }
 5         // dp1数组存储第`i`天,持有股票的最大利润
 6         int[][] dp1 = new int[2][a.length];
 7         dp1[0][0] = -a[0];dp1[1][0] = -a[0];
 8         // dp2数组存储第`i`天,不持有股票的最大利润
 9         int[][] dp2 = new int[2][a.length];
10         dp2[0][0] = 0;
11 
12         for (int i = 1; i < a.length; i++) {
13             dp1[0][i] = Math.max(dp1[0][i-1], -a[i]);//还有两次交易机会:前一天就持股,今天不操作;前一天没有持股,今天买
14             dp1[1][i] = Math.max(dp1[1][i-1], dp2[0][i-1]-a[i]);//还有一次交易机会:前一天就持股,今天不操作;前一天没有持股,今天买
15             dp2[0][i] = Math.max(dp2[0][i-1], a[i] + dp1[0][i-1]);//还有两次交易机会:前一天就没有持股,今天不操作;前一天持股,今天卖
16             dp2[1][i] = Math.max(dp2[1][i-1], a[i] + dp1[1][i-1]);//还有一次交易机会:前一天就没有持股,今天不操作;前一天有持股,今天卖
17         }
18         int maxProfit = dp2[1][a.length - 1];
19         System.out.println("最大利润:"+maxProfit);
20         return maxProfit;
21     }
java

 

六.leetcode 188:你最多可以完成 k 笔交易

将上面5的二维数组中0和1换成变量k,可以根据k=1,k=2,k>2,分情况处理