@@ -394,6 +394,7 @@ int maxProfit_k_any(int max_k, int[] prices) {
394
394
[Hanmin](https:// github.com/ Miraclemin/ ) 提供 Python3 代码:
395
395
396
396
** 第一题,k = 1 **
397
+
397
398
```python
398
399
def maxProfit(self , prices: List[int ]) -> int :
399
400
dp_i_0,dp_i_1 = 0 ,float (' -inf' )
@@ -403,6 +404,7 @@ def maxProfit(self, prices: List[int]) -> int:
403
404
return dp_i_0
404
405
```
405
406
** 第二题,k = + infinity**
407
+
406
408
```python
407
409
def maxProfit_k_inf(self , prices: List[int ]) -> int :
408
410
dp_i_0,dp_i_1 = 0 ,float (' -inf' )
@@ -413,6 +415,7 @@ def maxProfit_k_inf(self, prices: List[int]) -> int:
413
415
return dp_i_0
414
416
```
415
417
** 第三题,k = + infinity with cooldown**
418
+
416
419
```python
417
420
def maxProfit_with_cool(self , prices: List[int ]) -> int :
418
421
dp_i_0,dp_i_1 = 0 ,float (' -inf' )
@@ -435,6 +438,7 @@ def maxProfit_with_fee(self, prices: List[int], fee: int) -> int:
435
438
return dp_i_0
436
439
```
437
440
** 第五题,k = 2 **
441
+
438
442
```python
439
443
def maxProfit_k_2(self , prices: List[int ]) -> int :
440
444
dp_i10,dp_i11 = 0 ,float (' -inf' )
@@ -447,6 +451,7 @@ def maxProfit_k_2(self, prices: List[int]) -> int:
447
451
return dp_i20
448
452
```
449
453
** 第六题,k = any integer**
454
+
450
455
```python
451
456
def maxProfit_k_any(self , max_k: int , prices: List[int ]) -> int :
452
457
n = len (prices)
@@ -470,6 +475,154 @@ def maxProfit_k_any(self, max_k: int, prices: List[int]) -> int:
470
475
dp[i][k][1 ] = max (dp[i- 1 ][k][1 ], dp[i- 1 ][k- 1 ][0 ] - prices[i])
471
476
return dp[n - 1 ][max_k][0 ];
472
477
```
478
+ [z2z23n0](https:// github.com/ YuzeZhang/ ) 提供 C++ 代码:
479
+
480
+ ** 第一题,k = 1 **
481
+
482
+ ```c++
483
+ int maxProfit(vector< int > & prices) {
484
+ int n = prices.size();
485
+ // base case
486
+ int dp_i_0 = 0 , dp_i_1 = INT_MIN ;
487
+ // dp_i_0: 第i天的最大利润, 0 表示不持有股票
488
+ // dp_i_1: 第i天的最大利润, 1 表示持有股票
489
+
490
+ for (int i = 1 ; i <= n; i++ ) {
491
+ // 如果今天不持有股票,表示昨天也不持有股票或是今天卖掉了股票
492
+ dp_i_0 = max (dp_i_0, dp_i_1 + prices[i - 1 ]);
493
+ // 如果今天持有股票,表示昨天就持有股票或是今天买了股票
494
+ dp_i_1 = max (dp_i_1, - prices[i - 1 ]);
495
+ }
496
+ return dp_i_0;
497
+ }
498
+ ```
499
+
500
+ ** 第二题,k = + infinity**
501
+
502
+ ```c++
503
+ int maxProfit(vector< int > & prices) {
504
+ int n = prices.size();
505
+ // base case
506
+ int dp_i_0 = 0 , dp_i_1 = INT_MIN ;
507
+ // dp_i_0: 第i天的最大利润, 0 表示不持有股票
508
+ // dp_i_1: 第i天的最大利润, 1 表示持有股票
509
+
510
+ for (int i = 1 ; i <= n; i++ ) {
511
+ int temp = dp_i_0;
512
+ // 如果今天不持有股票,表示昨天也不持有股票或是今天卖掉了股票
513
+ dp_i_0 = std::max (dp_i_0, dp_i_1 + prices[i - 1 ]);
514
+ // 如果今天持有股票,表示昨天就持有股票或是今天买了股票
515
+ dp_i_1 = std::max (dp_i_1, temp - prices[i - 1 ]);
516
+ }
517
+
518
+ return dp_i_0;
519
+ }
520
+ ```
521
+
522
+ ** 第三题,k = + infinity with cooldown**
523
+
524
+ ```c++
525
+ int maxProfit(vector< int > & prices) {
526
+ int n = prices.size();
527
+ // base case
528
+ // dp_i_0: 第i天的最大利润, 0 表示不持有股票
529
+ // dp_i_1: 第i天的最大利润, 1 表示持有股票
530
+ int dp_i_0 = 0 , dp_i_1 = INT_MIN ;
531
+ // 表示第(i- 2 )天的最大利润,并且未持有股票
532
+ int prev_dp_i_0 = 0 ;
533
+ for (int i = 1 ; i <= n; i++ ) {
534
+ // temp和prev_dp_i_0用来记录第(i- 2 )天(前天)的最大利润
535
+ int temp = dp_i_0;
536
+ // 如果今天不持有股票,表示昨天也不持有股票或是今天卖掉了股票
537
+ dp_i_0 = std::max (dp_i_0, dp_i_1 + prices[i - 1 ]);
538
+ // 如果今天持有股票,表示昨天就持有股票或是今天买了股票
539
+ dp_i_1 = std::max (dp_i_1, prev_dp_i_0 - prices[i - 1 ]);
540
+ prev_dp_i_0 = temp;
541
+ }
542
+ return dp_i_0;
543
+ }
544
+ ```
545
+
546
+ ** 第四题,k = + infinity with fee**
547
+
548
+ ```c++
549
+ int maxProfit(vector< int > & prices, int fee) {
550
+ int n = prices.size();
551
+ // base case
552
+ int dp_i_0 = 0 , dp_i_1 = INT_MIN ;
553
+ // dp_i_0: 第i天的最大利润, 0 表示不持有股票
554
+ // dp_i_1: 第i天的最大利润, 1 表示持有股票
555
+
556
+ for (int i = 1 ; i <= n; i++ ) {
557
+ int temp = dp_i_0;
558
+ // 如果今天不持有股票,表示昨天也不持有股票或是今天卖掉了股票
559
+ dp_i_0 = std::max (dp_i_0, dp_i_1 + prices[i - 1 ]);
560
+ // 如果今天持有股票,表示昨天就持有股票或是今天买了股票
561
+ // tips:为什么不在卖股票的时候减掉transaction fee?因为在base case中, dp_i_1 == INT_MIN , INT_MIN + prices[i] - fee 可能会造成整型溢出
562
+ dp_i_1 = std::max (dp_i_1, temp - prices[i - 1 ] - fee);
563
+ }
564
+ return dp_i_0;
565
+ }
566
+ ```
567
+
568
+ ** 第五题,k = 2 **
569
+
570
+ ```c++
571
+ int maxProfit(vector< int > & prices) {
572
+ int size = prices.size();
573
+ int max_k = 2 ;
574
+
575
+ // i从1 开始而不是0 ,这样可以使base case是 dp[0 ][0 ][0 ] 和 dp[0 ][0 ][1 ] 而不是 dp[- 1 ][0 ][0 ] 或者 dp[- 1 ][0 ]
576
+ int dp[size + 1 ][max_k + 1 ][2 ];
577
+
578
+ // 初始化
579
+ for (int k = max_k; k >= 0 ; k-- ) {
580
+ dp[0 ][k][0 ] = 0 ;
581
+ dp[0 ][k][1 ] = INT_MIN ;
582
+ }
583
+
584
+ for (int i = 1 ; i <= size; i++ ) {
585
+ dp[i][0 ][0 ] = 0 ;
586
+ dp[i][0 ][1 ] = INT_MIN ;
587
+ for (int k = max_k; k >= 1 ; k-- ) {
588
+ dp[i][k][0 ] = std::max (dp[i - 1 ][k][0 ], dp[i - 1 ][k][1 ] + prices[i - 1 ]);
589
+ dp[i][k][1 ] = std::max (dp[i - 1 ][k][1 ], dp[i - 1 ][k - 1 ][0 ] - prices[i - 1 ]);
590
+ }
591
+ }
592
+ return dp[size][max_k][0 ];
593
+ }
594
+ ```
595
+
596
+ ** 第六题,k = any integer**
597
+
598
+ ```c++
599
+ int maxProfit(int k, vector< int > & prices) {
600
+ int size = prices.size();
601
+
602
+ if (k > size / 2 ) {
603
+ return maxProfitLimitless(prices);
604
+ }
605
+ // i从1 开始而不是0 ,这样可以使base case是 dp[0 ][0 ][0 ] 和 dp[0 ][0 ][1 ] 而不是 dp[- 1 ][0 ][0 ] 或者 dp[- 1 ][0 ][1 ]
606
+ int dp[size + 1 ][k + 1 ][2 ];
607
+
608
+ // 初始化
609
+ for (int j = k; j >= 0 ; j-- ) {
610
+ dp[0 ][j][0 ] = 0 ;
611
+ dp[0 ][j][1 ] = INT_MIN ;
612
+ }
613
+
614
+ for (int i = 1 ; i <= size; i++ ) {
615
+ dp[i][0 ][0 ] = 0 ;
616
+ dp[i][0 ][1 ] = INT_MIN ;
617
+ for (int j = k; j >= 1 ; j-- ) {
618
+ dp[i][j][0 ] = std::max (dp[i - 1 ][j][0 ], dp[i - 1 ][j][1 ] + prices[i - 1 ]);
619
+ dp[i][j][1 ] = std::max (dp[i - 1 ][j][1 ], dp[i - 1 ][j - 1 ][0 ] - prices[i - 1 ]);
620
+ }
621
+ }
622
+ return dp[size][k][0 ];
623
+ }
624
+ ```
625
+
473
626
[上一篇:动态规划之KMP 字符匹配算法](../ 动态规划系列/ 动态规划之KMP 字符匹配算法.md)
474
627
475
628
[下一篇:团灭 LeetCode 打家劫舍问题](../ 动态规划系列/ 抢房子.md)
0 commit comments