1
- public class Solution188 {
2
- public int maxProfit (int k , int [] prices ) {
3
- int len = prices .length ;
4
- if (len == 0 ) {
5
- return 0 ;
6
- }
7
-
8
- // 因为 n 天最多只能进行 floor(len/2) 笔交易
9
- k = Math .min (k , len / 2 );
10
-
11
- // buy[i][j] 表示对于数组 prices[0,i] 中的价格而言,进行恰好 j 笔交易,并且当前手上持有一支股票,这种情况下的最大利润
12
- // sell[i][j] 表示恰好进行 j 笔交易,并且当前手上不持有股票,这种情况下的最大利润
13
- int [][] buy = new int [len ][k + 1 ];
14
- int [][] sell = new int [len ][k + 1 ];
1
+ import java .util .Arrays ;
15
2
16
- // 初始状态
17
- buy [0 ][0 ] = -prices [0 ];
18
- sell [0 ][0 ] = 0 ;
19
- for (int i = 1 ; i <= k ; ++i ) {
20
- buy [0 ][i ] = sell [0 ][i ] = Integer .MIN_VALUE / 2 ;
21
- }
3
+ public class Solution188 {
4
+ private int [] prices ;
5
+ private int [][][] memo ;
22
6
23
- // 状态转移
24
- for (int i = 1 ; i < len ; ++i ) {
25
- buy [i ][0 ] = Math .max (buy [i - 1 ][0 ], sell [i - 1 ][0 ] - prices [i ]);
26
- for (int j = 1 ; j <= k ; ++j ) {
27
- buy [i ][j ] = Math .max (buy [i - 1 ][j ], sell [i - 1 ][j ] - prices [i ]);
28
- sell [i ][j ] = Math .max (sell [i - 1 ][j ], buy [i - 1 ][j - 1 ] + prices [i ]);
7
+ public int maxProfit (int k , int [] prices ) {
8
+ this .prices = prices ;
9
+ int n = prices .length ;
10
+ memo = new int [n ][k + 1 ][2 ];
11
+ for (int i = 0 ; i < n ; i ++) {
12
+ for (int j = 0 ; j < k + 1 ; j ++) {
13
+ Arrays .fill (memo [i ][j ], -1 );
29
14
}
30
15
}
16
+ return dfs (n - 1 , k , 0 );
17
+ }
31
18
32
- int max = 0 ;
33
- for (int x : sell [len - 1 ]) {
34
- max = Math .max (max , x );
19
+ // dfs(i, 0) 表示到第 i 天结束时完成至多 j 笔交易,未持有股票的最大利润
20
+ // dfs(i, 1) 表示到第 i 天结束时完成至多 j 笔交易,持有股票的最大利润
21
+ // 第 i-1 天结束就是第 i 天的开始
22
+ private int dfs (int i , int j , int hold ) {
23
+ if (j < 0 ) return (int ) -1e9 ;
24
+ if (i < 0 ) {
25
+ if (hold == 1 ) return (int ) -1e9 ;
26
+ return 0 ;
35
27
}
36
- return max ;
28
+ if (memo [i ][j ][hold ] != -1 ) return memo [i ][j ][hold ];
29
+ int res ;
30
+ if (hold == 1 ) res = Math .max (dfs (i - 1 , j , 1 ), dfs (i - 1 , j - 1 , 0 ) - prices [i ]);
31
+ else res = Math .max (dfs (i - 1 , j , 0 ), dfs (i - 1 , j , 1 ) + prices [i ]);
32
+ return memo [i ][j ][hold ] = res ;
37
33
}
38
34
}
39
35
/*
@@ -48,5 +44,5 @@ public int maxProfit(int k, int[] prices) {
48
44
0 <= prices.length <= 1000
49
45
0 <= prices[i] <= 1000
50
46
51
- 动态规划
47
+ 状态机 DP
52
48
*/
0 commit comments