买卖股票的最佳时机3

问题描述

给定i天内的股票走势,求在i天内进行两次交易所能获取的最大利润。

思路

1.给出差值数组,求连续正值的最大和和次大和。但是在下面这个例子中:
[3, 1, 4, 2, 6, 1, 3, 2, 5]
差值数组是 [-2,3,-2,4,-5,2,-1,3]
实际收益可以达到9,但是连续正值数组的最大和次大和是7,这种思路的问题在于如果在涨跌涨的情况下,我的思路其实放过了这个区间。
2.动态规划的思路:
<1> DP数组含义:DP数组必然代表了某天所能获得的最大利润,在这个过程中,这一天发生的可能是
(1).没有进行交易操作;
(2)进行了一次买入;
(3)进行了一次卖出;
(4)进行了二次买入;
(5)进行了二次卖出。
<2>递推关系
<3>DP数组初始化
<4>遍历顺序
<5>数组递推过程

具体实现

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<int> dp (5,0);
        if(prices.size()==0) return 0;
        dp[1]=-prices[0];
        dp[3]=-prices[0];
        for(int i=1;i<prices.size();i++)
        {
            dp[1]=max(dp[1],dp[0]-prices[i]);
            dp[2]=max(dp[2],dp[1]+prices[i]);
            dp[3]=max(dp[3],dp[2]-prices[i]);
            dp[4]=max(dp[4],dp[3]+prices[i]);
        }
        return dp[4];
    }
};

买卖股票的最佳时机4

题目理解

给出一只股票在i天内的价格走势,可以无限次买入和卖出,求最大利润。

思路

意味着只有两种状态:持有与不持有;

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if(prices.size()==0) return 0;
        vector<vector<int>> dp(prices.size(),vector<int>(2*k+1,0));
        for(int j=1;j<2*k;j+=2){
            dp[0][j]=-prices[0];
        }
        for(int i=1;i<prices.size();i++){
            for(int j=0;j<2*k-1;j+=2){
            dp[i][j+1]=max(dp[i-1][j+1],dp[i-1][j]-prices[i]);
            dp[i][j+2]=max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
            }
            
        }
        return dp[prices.size()-1][2*k];
    }
};

买卖股票的最佳时机

问题描述

可以多次买入和卖出,但是每次卖出的第二天不能进行买入操作,即存在一天的冷冻期。

思路

<1>DP数组含义
当日可能的四种状态
1.持有
2.不持有可以买
3.不持有,今天卖出的
4.冷冻期
<2>递推公式
dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i],dp[i-1][3]-prices[i])
含义:今天如果持有股票,可能是因为昨天就持有股票;可能是因为昨天是冷冻期今天买了股票;可能是因为昨天不是冷冻期今天也可以买股票。
dp[i][1]=dp[i-1][1],dp[i-1][3]
如果今天不持有但可以买,可能昨天是冷冻期,或者昨天和今天一样不持有但可以买
dp[i][2]=dp[i-1][0]+prices[i]
dp[i][3]=dp[i-1][2]
<3>初始化
dp[0][0]=-prices[0];
dp[0][1]=0;
dp[0][2]=0;
dp[0][3]=0;

实现

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n =prices.size();
       vector<vector<int>> dp(n,vector<int>(4,0));
       if(n==0) return 0;
       dp[0][0]-=prices[0];
       for(int i=1;i<n;i++)
       {
        dp[i][0]=max(dp[i-1][0],max(dp[i-1][1]-prices[i],dp[i-1][3]-prices[i]));//今天持有因为昨天持有,或者不持有但是买入了
        dp[i][1]=max(dp[i-1][3],dp[i-1][1]);//
        dp[i][2]=dp[i-1][0]+prices[i];//今天不持有因为昨天卖出了
        dp[i][3]=dp[i-1][2];
       }
       return max(dp[n-1][3],max(dp[n-1][2],dp[n-1][1]));
    }
};

磕磕绊绊实现,对于dp[i][1]的状态还是有待顺通。

买卖股票的最佳时机含手续费

问题理解

卖出需要手续费

for (int i = 1; i < len; i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i-1][1]-prices[i]);
            dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]-fee);
        }
        return dp[len - 1][1];

股票问题总结

题目给定i天内的股票走势.求交易后的最大利润,条件分别是:
1.求只交易一次;
2.最多交易两次;
3.可以交易k次;
4.交易包含冷冻期一天;
5.交易需要手续费。
对于状态的理解,首先需要明确第i天可能由几种状态,其次在递推公式中明确当前的状态前一天的可能状态。动态规划中的动态就体现在目前的状态可能是不同的。

posted on 2025-12-17 19:25  FAfa_C++  阅读(3)  评论(0)    收藏  举报