五.接上一篇 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 }
六.leetcode 188:你最多可以完成 k 笔交易
将上面5的二维数组中0和1换成变量k,可以根据k=1,k=2,k>2,分情况处理