1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>
 4 using namespace std;
 5 
 6 
 7 
 8 /*
 9 dp[i][0] 表示第i天持有股票所得最多现金,
10 dp[i][1] 表示第i天不持有股票所得最多现金
11 
12 如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
13 (1) 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
14 (2) 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i],
15 为什么这里是 -price[i] ?  既然第i天买入,由于题目要求只能买卖一次,那么说明前面第i-1天
16 就没有买过股票,那么前面的第i-1天现金没有任何变动,此时第i天买入股票,那么就是要付出一笔价格为
17 price[i]的钱,所以付出了钱,所得现金就是 -price[0],我们这里只在乎现金的变动,变动!
18 那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);
19 
20 如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来
21 (1) 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
22 (2) 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0],
23 同样,我们也只在乎现金的变动,第i天卖出股票,说明前面不知道哪天有买入过股票,那么前面的现金有过
24 变动,所以这里不能只计算卖出的股票所得的现金 prices[i],还得再算上前面不知道哪天买入股票后所计算
25 出来的所得现金,这个现金累计可以累计到i-1天上,所以还要再加上第i-1天持有这支股票的所得现金dp[i - 1][0]
26 同样,我们这里只在乎现金的变动,变动!
27 同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
28 */
29 
30 /*   开辟一个 len*2 的二维数组,有len行2列,之所以有2列,是因为
31 dp[i][0] 表示第i天持有股票所得最多现金,
32 dp[i][1] 表示第i天不持有股票所得最多现金
33 这里只有持有和不持有两种状态
34 */
35 //dp 2
36 int MaxProfitmore(vector<int>& stocks){
37     int length = stocks.size();
38     vector<vector<int>> dp(length,vector<int> (5));
39     dp[0][1] = -stocks[0];
40     dp[0][3] = -stocks[0];
41     for(int i = 1;i < length;i++){
42         dp[i][1] = max(dp[i-1][1], dp[i-1][0] - stocks[i]);
43         dp[i][2] = max(dp[i-1][2], dp[i-1][1] + stocks[i]);
44         dp[i][3] = max(dp[i-1][3], dp[i-1][2] - stocks[i]);
45         dp[i][4] = max(dp[i-1][4], dp[i-1][3] + stocks[i]);
46     }    
47     //为什么返回dp[i][1]这个状态,而不是dp[i][0]?因为不持有股票状态所得的金钱一定比持有股票所得的金钱得到的多
48     return dp[length-1][4];
49 }
50 int main(void){
51     vector<int> stocks = {7,1,5,3,6,4};
52     printf("最大利润:%d\n",MaxProfitmore(stocks));
53     return 0;
54 }

 

posted on 2025-05-11 16:32  FYJUN2077  阅读(8)  评论(0)    收藏  举报